XdmfWeb XdmfWikiDB http://www.xdmf.org/index.php/Main_Page MediaWiki 1.39.11 first-letter Media Special Talk User User talk XdmfWeb XdmfWeb talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Main Page 0 1 1 2007-04-24T15:29:48Z MediaWiki default 0 wikitext text/x-wiki <big>'''MediaWiki has been successfully installed.'''</big> Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software. == Getting started == * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 928e1deea259c70afc3513c66f29f3fcd740d8bf 2 1 2007-05-03T12:44:36Z 128.63.127.201 0 /* Getting started */ wikitext text/x-wiki <big>'''MediaWiki has been successfully installed.'''</big> Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. [[XDMF Model and Format]]XdmfFormat.html * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] d9be7250556b620ada857dc14b218e9dc1c4d5e4 3 2 2007-05-03T12:49:51Z 128.63.127.201 0 wikitext text/x-wiki <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. [[XDMF Model and Format]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] e67842b4092bb1445b048f789bcf6aae1951c8a6 4 3 2007-05-03T12:50:09Z 128.63.127.201 0 wikitext text/x-wiki <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. [[XDMF Model and Format]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 363ff868419bd412806f3b4b350ee8f98271869f 11 4 2007-05-03T16:11:24Z 128.63.127.201 0 wikitext text/x-wiki <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. [[XDMF Model and Format]] [[XDMF API]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 54ee466d686258b8336f3c59f3dd661427b505b1 12 11 2007-05-03T16:11:38Z 128.63.127.201 0 wikitext text/x-wiki <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. [[XDMF Model and Format]] [[XDMF API]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 060efb6ed72e25cf6839bedf22306311609bf135 18 12 2007-05-03T16:56:23Z 128.63.127.211 0 wikitext text/x-wiki <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. [[XDMF Model and Format]] [[XDMF API]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] dcceb770b05ac221f3c1c0341e58d53f47f093bc 19 18 2007-05-03T16:57:23Z 128.63.127.211 0 wikitext text/x-wiki <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be Light (typically less than about a thousand values) of Heavy (megabytes, terabytes, etc.). In addition to raw values, data can refer to Format (rank and dimensions of an array) or Model (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. *[[XDMF Model and Format]] *[[XDMF API]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] fd423eb9bfdf8931dbc83bb6863233d2a56a66d5 20 19 2007-05-03T17:26:44Z 128.63.127.201 0 wikitext text/x-wiki <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 �attributes�, using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as �attributes� of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. *[[XDMF Model and Format]] *[[XDMF API]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 3a1504adde45eb801d32f5c386784ebd655b2b22 21 20 2007-05-03T17:27:35Z 128.63.127.201 0 wikitext text/x-wiki <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. *[[XDMF Model and Format]] *[[XDMF API]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 142f32c6dac290e62924d81c498127f95f931970 27 21 2007-05-03T21:21:48Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <big>e'''X'''tensible '''D'''ata '''M'''odel and '''F'''ormat</big> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. *[[XDMF Model and Format]] *[[XDMF API]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 025c9c88f49aeaa577661bbc2c286a96aa570c88 28 27 2007-05-03T21:28:31Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. *[[XDMF Model and Format]] *[[XDMF API]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 2cead3b12bef67c7d613826caab9e7c88ae46688 36 28 2007-05-04T13:48:47Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 0d9355bb102818041568cab7b8bc2117b8a860fc 46 36 2008-05-02T15:54:28Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 6ebf48a44498ce36299efa7a27fb537ad5fbe46c XDMF Model and Format 0 2 5 2007-05-03T14:11:51Z 128.63.127.201 0 New page: <p class=MsoNormal><b><span style='font-size:18.0pt;color:red'>XML</span></b></p> <p class=MsoNormal>The eXtensible Markup Language (XML) format is widely used for many purposes and is w... wikitext text/x-wiki <p class=MsoNormal><b><span style='font-size:18.0pt;color:red'>XML</span></b></p> <p class=MsoNormal>The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a &quot;personalized HTML&quot; with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF were primarily concerned with the elements. These elements follow the basic form :</p> <p class=MsoNormal style='margin-left:.5in'><span style='color:blue'>&lt;ElementTag</span></p> <p class=MsoNormal style='margin-left:1.0in'><span style='color:blue'>AttributeName=&quot;AttribteValue&quot;</span></p> <p class=MsoNormal style='margin-left:1.0in'><span style='color:blue'>AttributeName=&quot;AttributeValue&quot;</span></p> <p class=MsoNormal style='margin-left:1.0in'><span style='color:blue'> .. &gt;</span></p> <p class=MsoNormal style='margin-left:1.5in'><b><i><span style='color:blue'>CData</span></i></b></p> <p class=MsoNormal style='margin-left:.5in'><span style='color:blue'>&lt;/ElementTag&gt;</span></p> <p class=MsoNormal>Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several &quot;Name=Value&quot; pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then &quot;serialized&quot; back into XML.</p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>Comment in XML start with a &lt;!-- and end with a --&gt;.� So &lt;!--This is a Comment --&gt;.</p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>XML is said to be well formed if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be valid if it conforms to the <i>Schema</i> or <i>DTD</i> defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML :</p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal><b>XInclude</b></p> <p class=MsoNormal>As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this :</p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal><b><span style='color:blue'>&lt;Xdmf Version=&quot;2.0&quot; xmlns:xi=&quot;</span></b><span style='color:blue'><a href="http://www.w3.org/2001/XInclude"><b><span style='color:blue'>http://www.w3.org/2001/XInclude</span></b></a><b>&quot;&gt;</b></span></p> <p class=MsoNormal><b><span style='color:blue'>&lt;xi:include href=&quot;Example3.xmf&quot;/&gt;</span></b></p> <p class=MsoNormal><b><span style='color:blue'>&lt;/Xdmf&gt;</span></b></p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL.</p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal><b>XPath</b></p> <p class=MsoNormal>This allows for elements in the XML document and the API to reference specific elements in a document. For example :</p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>The first Grid in the first Domain</p> <p class=MsoNormal><b><span style='color:blue'>/Xdmf/Domain/Grid</span></b></p> <p class=MsoNormal>The tenth Grid .... XPath is one based.</p> <p class=MsoNormal><b><span style='color:blue'>/Xdmf/Domain/Grid[10]</span></b></p> <p class=MsoNormal>The first grid with an attribute <i>Name</i> which has a value of <i>Copper Plate</i></p> <p class=MsoNormal><b><span style='color:blue'>/Xdmf/Domain/Grid[@Name=Copper Plate]</span></b></p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal>All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be :</p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal><b><span style='color:blue'>&lt;?xml version=&quot;1.0&quot; ?&gt;</span></b></p> <p class=MsoNormal><b><span style='color:blue'>&lt;!DOCTYPE Xdmf SYSTEM &quot;Xdmf.dtd&quot; []&gt;</span></b></p> <p class=MsoNormal><b><span style='color:blue'>&lt;Xdmf Version=2.0&gt;</span></b></p> <p class=MsoNormal><b><span style='color:blue'>&lt;/Xdmf&gt;</span></b></p> <p class=MsoNormal><b><span style='color:blue'>&nbsp;</span></b></p> <p class=MsoNormal>While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled.</p> <p class=MsoNormal>&nbsp;</p> <p class=MsoNormal><b><span style='font-size:18.0pt;color:red'>XDMF Elements</span></b></p> <p class=MsoNormal>&nbsp;</p> 0d47bb2b19d3aab3bda4a3d1179303c24322a504 6 5 2007-05-03T14:29:07Z 128.63.127.201 0 wikitext text/x-wiki The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we\�re primarily concerned with the elements. These elements follow the basic form : <ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" �.. > ''CData'' </ElementTag> Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">''' '''<xi:include href="Example3.xmf"/>''' '''</Xdmf>''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid\[10\]''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid\[@Name="Copper Plate"\]''' All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be : '''<?xml version="1.0" ?>''' '''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" \[\]>''' '''<Xdmf Version="2.0">''' '''</Xdmf>''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' � this is the default. A single array of values. # '''Collection''' � a one dimension array of DataItems # '''Tree''' � a hierarchical structure of DataItems # '''HyperSlab''' � contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' � contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' � calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''<DataItem Dimensions="3">''' '''1.0 2.0 3.0''' '''</DataItem>''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''<DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3">''' '''1.0 2.0 3.0''' '''</DataItem>''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''<DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256">''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''</DataItem>''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''<DataItem Name="Tree Example" ItemType="Tree">''' '''<DataItem ItemType="Tree">''' '''<DataItem Name="Collection 1" ItemType="Collection">''' '''<DataItem Dimensions="3">''' '''1.0 2.0 3.0''' '''</DataItem>''' '''<DataItem Dimensions="4">''' '''4 5 6 7''' '''</DataItem>''' '''</DataItem>''' '''</DataItem>''' '''<DataItem Name="Collection 2" ItemType="Collection">''' '''<DataItem Dimensions="3">''' '''7 8 9''' '''</DataItem>''' '''<DataItem Dimensions="4">''' '''10 11 12 13''' '''</DataItem>''' '''</DataItem>''' '''<DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256">''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''</DataItem>''' '''</DataItem>''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at \[0,0,0,0\], ending at \[50, 100, 150, 2\] that includes every other plane of data with the HyperSlab DataItem '''<DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab">''' '''<DataItem''' '''Dimensions="3 4"''' '''Format="XML">''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''</DataItem>''' '''<DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF">''' '''MyData.h5:/XYZ''' '''</DataItem>''' '''</DataItem>''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''<DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab">''' '''<DataItem''' '''Dimensions="2 4"''' '''Format="XML">''' '''0 0 0 1''' '''99 199 299 0''' '''</DataItem>''' '''<DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF">''' '''MyData.h5:/XYZ''' '''</DataItem>''' '''</DataItem>''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''<DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3">''' '''<DataItem Dimensions="3">''' '''1.0 2.0 3.0''' '''</DataItem>''' '''<DataItem Dimensions="3">''' '''4.1 5.2 6.3''' '''</DataItem>''' '''</DataItem>''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''<DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0">''' ''' <DataItem Reference="/Xdmf/DataItem\[1\]" />''' ''' </DataItem>''' Multiply two arrays (element by element) and take the absolute value ''' <DataItem ItemType="Function"''' ''' Function="ABS($0 \* $1)">''' ''' <DataItem Reference="/Xdmf/DataItem\[1\]" />''' ''' <DataItem Reference="/Xdmf/DataItem\[2\]" />''' ''' </DataItem>''' Select element 5 thru 15 from the first DataItem ''' <DataItem ItemType="Function"''' ''' Function="$0\[5:15\]">''' ''' <DataItem Reference="/Xdmf/DataItem\[1\]" />''' ''' </DataItem>''' Concat two arrays ''' <DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)">''' ''' <DataItem Reference="/Xdmf/DataItem\[1\]" />''' ''' <DataItem Reference="/Xdmf/DataItem\[2\]" />''' ''' </DataItem>''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' <DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)">''' ''' <DataItem Reference="/Xdmf/DataItem\[1\]" />''' ''' <DataItem Reference="/Xdmf/DataItem\[2\]" /> ''' ''' <DataItem Reference="/Xdmf/DataItem\[3\]" />''' ''' </DataItem>''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' � a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' � an array of Uniform grids # '''Tree''' � a hierarchical group # '''SubSet '''� a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''<Grid Name="Car Wheel" GridType="Tree">''' '''<Grid Name="Tire" GridType="Uniform">''' '''<Topology �.''' '''<Geometry �''' '''</Grid>''' '''<Grid Name="Lug Nuts" GridType="Collection">''' '''<Grid Name="Lug Nut 0" GridType="Uniform"''' '''<Topology �.''' '''<Geometry �''' '''</Grid>''' '''<Grid Name="Lug Nut 1" GridType="Uniform"''' '''<Topology �.''' '''<Geometry �''' '''</Grid>''' '''<Grid Name="Lug Nut 2" GridType="Uniform"''' '''<Topology �.''' '''<Geometry �''' '''</Grid>''' '''</Grid>''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' <Grid Name="Portion" GridType="Subset" Section="DataItem">''' ''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther'' ''' <DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML">''' ''' 0 2''' ''' </DataItem>''' ''' <Grid Name="Target" Reference="XML">''' ''' /Xdmf/Domain/Grid\[@Name="Main Grid"\]''' ''' </Grid>''' ''' <Attribute Name="New Values" Center="Cell">''' ''' <DataItem Format="XML" Dimensions="2">''' ''' 100 150''' ''' </DataItem>''' ''' </Attribute>''' ''' </Grid>''' '''Or ''' ''' <Grid Name="Portion" GridType="Subset" Section="All">''' ''<!-- Select the entire grid and add an attribute -->'' ''' <Grid Name="Target" Reference="XML">''' ''' /Xdmf/Domain/Grid\[@Name="Main Grid"\]''' ''' </Grid>''' ''' <Attribute Name="New Values" Center="Cell">''' ''' <DataItem Format="XML" Dimensions="3">''' ''' 100 150 200''' ''' </DataItem>''' ''' </Attribute>''' ''' </Grid>''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex � a group of unconnected points * Polyline � a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 � Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed � a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh � Axis are perpendicular * 2DCoRectMesh � Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''<Topology Type="Quadrilateral" NumberOfElements="2" >''' '''<DataItem Format="XML" DataType="Int" Dimensions="2 4">''' '''0 1 2 3''' '''1 6 7 2''' '''</DataItem>''' '''</Topology>''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''<Topology Type="Mixed" NumberOfElements="3" >''' '''<DataItem Format="XML" DataType="Int" Dimensions="20">''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''</DataItem>''' '''</Topology>''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''<Geometry Type="XYZ">''' '''<DataItem Format="XML" Dimensions="2 4 3">''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''</DataItem>''' '''</Geometry>''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''<?xml version="1.0" ?>''' '''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" \[\]>''' '''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">''' '''<Domain>''' '''<Grid Name="Two Quads>''' '''<Topology Type="Quadrilateral" NumberOfElements="2" >''' '''<DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4">''' '''0 1 2 3''' '''1 6 7 2''' '''</DataItem>''' '''</Topology>''' '''<Geometry Type="XYZ">''' '''<DataItem Format="XML" Dimensions="2 4 3">''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''</DataItem>''' '''</Geometry>''' '''</Grid>''' '''</Domain>''' '''</Xdmf>''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''<?xml version="1.0" ?>''' '''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" \[\]>''' '''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">''' '''<Domain>''' '''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''</DataItem>''' '''<Grid Name="Two Quads>''' '''<Topology Type="Quadrilateral" NumberOfElements="2" >''' '''<DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4">''' '''0 1 2 3''' '''1 6 7 2''' '''</DataItem>''' '''</Topology>''' '''<Geometry Type="XYZ">''' '''<DataItem Reference="XML">''' '''/Xdmf/Domain/DataItem\[@Name="Point Data"\]''' '''</DataItem>''' '''</Geometry>''' '''</Grid>''' '''</Domain>''' '''</Xdmf>''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' � 9 values expected * '''Tensor6''' � a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don\�t map well to many visualization systems. Typically Attributes are assigned on the Node : '''<Attribute Name="Node Values" Center="Node">''' '''<DataItem Format="XML" Dimensions="6 4">''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''</DataItem>''' '''</Attribute>''' Or assigned to the cell centers : '''<Attribute Name="Cell Values" Center="Cell">''' '''<DataItem Format="XML" Dimensions="3">''' ''' 3000 2000 1000''' ''' </DataItem>''' '''</Attribute>''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''<Information Name="XBounds" Value="0.0 10.0"/>''' '''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. 2a26feee31176feab7926403503f0327f603e543 7 6 2007-05-03T14:33:58Z 128.63.127.201 0 wikitext text/x-wiki The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>�</nowiki>re primarily concerned with the elements. These elements follow the basic form : <ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" �.. > ''CData'' </ElementTag> Each element begins with an <tag> and ends with a </tag>. Optionally there can be several "Name=Value" pairs which convey additional information. Between the <tag> and the </tag> there can be other <tag></tag> pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "<!--" and end with a "-->". So <!--This is a Comment -->. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">''' '''<xi:include href="Example3.xmf"/>''' '''</Xdmf>''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the <Xdmf> and the </Xdmf>. So a minimal (empty) XDMF XML file would be : '''<?xml version="1.0" ?>''' '''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>''' '''<Xdmf Version="2.0">''' '''</Xdmf>''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' � this is the default. A single array of values. # '''Collection''' � a one dimension array of DataItems # '''Tree''' � a hierarchical structure of DataItems # '''HyperSlab''' � contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' � contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' � calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''<DataItem Dimensions="3">''' '''1.0 2.0 3.0''' '''</DataItem>''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''<DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3">''' '''1.0 2.0 3.0''' '''</DataItem>''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''<DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256">''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''</DataItem>''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''<DataItem Name="Tree Example" ItemType="Tree">''' '''<DataItem ItemType="Tree">''' '''<DataItem Name="Collection 1" ItemType="Collection">''' '''<DataItem Dimensions="3">''' '''1.0 2.0 3.0''' '''</DataItem>''' '''<DataItem Dimensions="4">''' '''4 5 6 7''' '''</DataItem>''' '''</DataItem>''' '''</DataItem>''' '''<DataItem Name="Collection 2" ItemType="Collection">''' '''<DataItem Dimensions="3">''' '''7 8 9''' '''</DataItem>''' '''<DataItem Dimensions="4">''' '''10 11 12 13''' '''</DataItem>''' '''</DataItem>''' '''<DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256">''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''</DataItem>''' '''</DataItem>''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''<DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab">''' '''<DataItem''' '''Dimensions="3 4"''' '''Format="XML">''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''</DataItem>''' '''<DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF">''' '''MyData.h5:/XYZ''' '''</DataItem>''' '''</DataItem>''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''<DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab">''' '''<DataItem''' '''Dimensions="2 4"''' '''Format="XML">''' '''0 0 0 1''' '''99 199 299 0''' '''</DataItem>''' '''<DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF">''' '''MyData.h5:/XYZ''' '''</DataItem>''' '''</DataItem>''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''<DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3">''' '''<DataItem Dimensions="3">''' '''1.0 2.0 3.0''' '''</DataItem>''' '''<DataItem Dimensions="3">''' '''4.1 5.2 6.3''' '''</DataItem>''' '''</DataItem>''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''<DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0">''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />''' ''' </DataItem>''' Multiply two arrays (element by element) and take the absolute value ''' <DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)">''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />''' ''' </DataItem>''' Select element 5 thru 15 from the first DataItem ''' <DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>">''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />''' ''' </DataItem>''' Concat two arrays ''' <DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)">''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" />''' ''' </DataItem>''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' <DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)">''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" />''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /> ''' ''' <DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" />''' ''' </DataItem>''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' � a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' � an array of Uniform grids # '''Tree''' � a hierarchical group # '''SubSet '''� a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''<Grid Name="Car Wheel" GridType="Tree">''' '''<Grid Name="Tire" GridType="Uniform">''' '''<Topology �.''' '''<Geometry �''' '''</Grid>''' '''<Grid Name="Lug Nuts" GridType="Collection">''' '''<Grid Name="Lug Nut 0" GridType="Uniform"''' '''<Topology �.''' '''<Geometry �''' '''</Grid>''' '''<Grid Name="Lug Nut 1" GridType="Uniform"''' '''<Topology �.''' '''<Geometry �''' '''</Grid>''' '''<Grid Name="Lug Nut 2" GridType="Uniform"''' '''<Topology �.''' '''<Geometry �''' '''</Grid>''' '''</Grid>''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' <Grid Name="Portion" GridType="Subset" Section="DataItem">''' ''<!-- Select 2 cells from another grid. Which 2 are defined by the DataItem -->Ther'' ''' <DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML">''' ''' 0 2''' ''' </DataItem>''' ''' <Grid Name="Target" Reference="XML">''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' </Grid>''' ''' <Attribute Name="New Values" Center="Cell">''' ''' <DataItem Format="XML" Dimensions="2">''' ''' 100 150''' ''' </DataItem>''' ''' </Attribute>''' ''' </Grid>''' '''Or ''' ''' <Grid Name="Portion" GridType="Subset" Section="All">''' ''<!-- Select the entire grid and add an attribute -->'' ''' <Grid Name="Target" Reference="XML">''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' </Grid>''' ''' <Attribute Name="New Values" Center="Cell">''' ''' <DataItem Format="XML" Dimensions="3">''' ''' 100 150 200''' ''' </DataItem>''' ''' </Attribute>''' ''' </Grid>''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex � a group of unconnected points * Polyline � a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 � Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed � a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh � Axis are perpendicular * 2DCoRectMesh � Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''<Topology Type="Quadrilateral" NumberOfElements="2" >''' '''<DataItem Format="XML" DataType="Int" Dimensions="2 4">''' '''0 1 2 3''' '''1 6 7 2''' '''</DataItem>''' '''</Topology>''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''<Topology Type="Mixed" NumberOfElements="3" >''' '''<DataItem Format="XML" DataType="Int" Dimensions="20">''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''</DataItem>''' '''</Topology>''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''<Geometry Type="XYZ">''' '''<DataItem Format="XML" Dimensions="2 4 3">''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''</DataItem>''' '''</Geometry>''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''<?xml version="1.0" ?>''' '''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>''' '''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">''' '''<Domain>''' '''<Grid Name="Two Quads>''' '''<Topology Type="Quadrilateral" NumberOfElements="2" >''' '''<DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4">''' '''0 1 2 3''' '''1 6 7 2''' '''</DataItem>''' '''</Topology>''' '''<Geometry Type="XYZ">''' '''<DataItem Format="XML" Dimensions="2 4 3">''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''</DataItem>''' '''</Geometry>''' '''</Grid>''' '''</Domain>''' '''</Xdmf>''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''<?xml version="1.0" ?>''' '''<!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>>''' '''<Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]">''' '''<Domain>''' '''<DataItem Name="Point Data" Format="XML" Dimensions="2 4 3">''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''</DataItem>''' '''<Grid Name="Two Quads>''' '''<Topology Type="Quadrilateral" NumberOfElements="2" >''' '''<DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4">''' '''0 1 2 3''' '''1 6 7 2''' '''</DataItem>''' '''</Topology>''' '''<Geometry Type="XYZ">''' '''<DataItem Reference="XML">''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''</DataItem>''' '''</Geometry>''' '''</Grid>''' '''</Domain>''' '''</Xdmf>''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' � 9 values expected * '''Tensor6''' � a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''<Attribute Name="Node Values" Center="Node">''' '''<DataItem Format="XML" Dimensions="6 4">''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''</DataItem>''' '''</Attribute>''' Or assigned to the cell centers : '''<Attribute Name="Cell Values" Center="Cell">''' '''<DataItem Format="XML" Dimensions="3">''' ''' 3000 2000 1000''' ''' </DataItem>''' '''</Attribute>''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''<Information Name="XBounds" Value="0.0 10.0"/>''' '''<Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information>''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. 8ee08590daab349dfb749ca1fe22aae405436cc3 8 7 2007-05-03T15:09:26Z 128.63.127.201 0 wikitext text/x-wiki The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>�</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" �.. &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' � this is the default. A single array of values. # '''Collection''' � a one dimension array of DataItems # '''Tree''' � a hierarchical structure of DataItems # '''HyperSlab''' � contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' � contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' � calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' � a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' � an array of Uniform grids # '''Tree''' � a hierarchical group # '''SubSet '''� a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex � a group of unconnected points * Polyline � a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 � Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed � a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh � Axis are perpendicular * 2DCoRectMesh � Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' � 9 values expected * '''Tensor6''' � a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. 1e3366ef206ac1e6217f7337a95bc3cf8be30c69 9 8 2007-05-03T16:05:26Z 128.63.127.211 0 wikitext text/x-wiki The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : <br> '''&lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt;''' <br> Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. 1d015b5af8daf126379d8f3474eccaa90d58c558 10 9 2007-05-03T16:08:54Z 128.63.127.211 0 wikitext text/x-wiki The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : <br> '''&lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt;''' <br> Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. 9ab5e308055d61d3f8cd053ffc33ca074f502f8e 16 10 2007-05-03T16:41:24Z 128.63.127.211 0 wikitext text/x-wiki The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology �.''' '''&lt;Geometry �''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. 8d1a01340a14441cacdbd5d748179b6e21bff2cf 17 16 2007-05-03T16:50:07Z 128.63.127.211 0 wikitext text/x-wiki The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. d0f6972305a28516c6bdbe4234a26f2eb5c8d9f8 29 17 2007-05-03T21:32:08Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. 7f410f1cd7517cefec942016c4213b7bce1f0aca 30 29 2007-05-03T21:32:29Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This only selects the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. 56d470a77e52ede8bbf457e96288915d28d606cf 32 30 2007-05-04T12:58:18Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element and Default XML Attributes''' * Attribute Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF * Domain Name (no default) * Geometry GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information Name (no default) Value (no default) * Xdmf Version <span style='color:red'>2.0</span> | * * Topology Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # bc63eb5dc0014536d85087b2fa598ee6b59c6f96 33 32 2007-05-04T13:01:48Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;Ther'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude-http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # 8d066a55f0c9d5eeec23c8eca3dc82e809a5bf44 40 33 2007-05-24T15:18:52Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set Type="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology Type="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # 5287284d706215d1d110d8bbe62d6caefa1904db 41 40 2007-08-27T13:24:06Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # 3cf7a4a7f54387bb99e220a28ee4c50f1c22166c 43 41 2008-02-01T14:43:47Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TypeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 3ade5e88ea6084d44e1b74e4a0950704a8d5d1b1 45 43 2008-05-01T16:05:57Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) of ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensative and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttribteValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with an &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds an tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comment in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. This is all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt;. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stide, and count of the vales in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinated of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concat or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concat two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attribute on grid. This allows users to share the geometry and toplogy of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grid share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but don<nowiki>�</nowiki>t map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TypeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 2ff5fe9a35b797b01930e81bf0f3519784ccab19 XDMF API 0 3 13 2007-05-03T16:11:57Z 128.63.127.201 0 New page: '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give a... wikitext text/x-wiki '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parser strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>�</nowiki>MyXMLFile.xmf<nowiki>�</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki>�</nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet(<nowiki>�</nowiki>Domain<nowiki>�</nowiki>) <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement(<nowiki>�</nowiki>Grid<nowiki>�</nowiki>, 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath(<nowiki>�</nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki>�</nowiki>) <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, <nowiki>�</nowiki>Name<nowiki>�</nowiki>) SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki>�</nowiki>Grid<nowiki>�</nowiki>) Status = XdmfDOM.Set(SubGrid, <nowiki>�</nowiki>Name<nowiki>�</nowiki>, <nowiki>�</nowiki>My SubGrid<nowiki>�</nowiki>) And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write(<nowiki>�</nowiki>MyFile.xmf<nowiki>�</nowiki>) '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath(<nowiki>�</nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki>�</nowiki>) Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>�</nowiki>Name<nowiki>�</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, <nowiki>�</nowiki>Name<nowiki>�</nowiki>) For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set(<nowiki>�</nowiki>Name<nowiki>�</nowiki>, <nowiki>�</nowiki>My Grid<nowiki>�</nowiki>) Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz-&gt;SetNumberType(XDMF_FLOAT64_TYPE) xyz-&gt;SetShape(3, dims); // KDim, JDim, IDim xyz-&gt;SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz-&gt;SetValues(1, y, total, 3, 1); xyz-&gt;SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import <nowiki>*</nowiki> def Expression(<nowiki>*</nowiki>args) : e = <nowiki>�</nowiki><nowiki>�</nowiki> for arg in args : if hasattr(arg, <nowiki>�</nowiki>GetTagName<nowiki>�</nowiki>) : e += arg.GetTagName() + <nowiki>�</nowiki> <nowiki>�</nowiki> else : e += arg + <nowiki>�</nowiki> <nowiki>�</nowiki> return XdmfExpr(e) if __name__ == <nowiki>�</nowiki>__main__<nowiki>�</nowiki> : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print <nowiki>�</nowiki>a1 Values = <nowiki>�</nowiki>, a1.GetValues() print <nowiki>�</nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki><nowiki>[</nowiki> 2:10 <nowiki>]</nowiki><nowiki>�</nowiki>).GetValues() print <nowiki>�</nowiki>a2 Values = <nowiki>�</nowiki>, a2.GetValues() print <nowiki>�</nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki><nowiki>[</nowiki><nowiki>�</nowiki>, a2, <nowiki>�</nowiki><nowiki>]</nowiki><nowiki>�</nowiki>).GetValues() print <nowiki>�</nowiki>a1 + a2 = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> + <nowiki>�</nowiki>, a2).GetValues() print <nowiki>�</nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> <nowiki>*</nowiki> <nowiki>�</nowiki>, a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print <nowiki>�</nowiki>a2 Values = <nowiki>�</nowiki>, a2.GetValues() print <nowiki>�</nowiki>a1 , a2 (Interlace) = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> , <nowiki>�</nowiki>, a2).GetValues() print <nowiki>�</nowiki>a1 , a2, a1 (Interlace) = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> , <nowiki>�</nowiki>, a2, <nowiki>�</nowiki> , <nowiki>�</nowiki>, a1).GetValues() print <nowiki>�</nowiki>a1 ; a2 (Concat) = <nowiki>�</nowiki> + Expression(a1 , <nowiki>�</nowiki> ; <nowiki>�</nowiki>, a2).GetValues() print <nowiki>�</nowiki>where(a1 &gt; 10) = <nowiki>�</nowiki> + Expression(<nowiki>�</nowiki>Where( <nowiki>�</nowiki>, a1 , <nowiki>�</nowiki> &gt; 10)<nowiki>�</nowiki>).GetValues() print <nowiki>�</nowiki>a2<nowiki>[</nowiki>where(a1 &gt; 10)<nowiki>]</nowiki> = <nowiki>�</nowiki> + Expression(a2, <nowiki>�</nowiki><nowiki>[</nowiki>Where( <nowiki>�</nowiki>, a1 , <nowiki>�</nowiki> &gt; 10)<nowiki>]</nowiki><nowiki>�</nowiki>).GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArray a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfHDF''' In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = <nowiki>�</nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75 �� Connectivity = <nowiki>�</nowiki>3 2 5 1 �. Values = <nowiki>�</nowiki>100 200 300 �.. <nowiki>#</nowiki> Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) <nowiki>#</nowiki> Open for Writing. This will truncate the file. H5.Open(<nowiki>�</nowiki>Example1.h5:/Geometry<nowiki>�</nowiki>, <nowiki>�</nowiki>w<nowiki>�</nowiki>) H5.Write(GeometryArray) H5.Close() <nowiki>#</nowiki> Connectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) <nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file. H5.Open(<nowiki>�</nowiki>Example1.h5:/Connectivity<nowiki>�</nowiki>, <nowiki>�</nowiki>rw<nowiki>�</nowiki>) H5.Write(ConnectivityArray) H5.Close() <nowiki>#</nowiki> Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) <nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file. H5.Open(<nowiki>�</nowiki>Example1.h5:/Values<nowiki>�</nowiki>, <nowiki>�</nowiki>rw<nowiki>�</nowiki>) H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open(<nowiki>�</nowiki>Example1.h5:/Values<nowiki>�</nowiki>, <nowiki>�</nowiki>rw<nowiki>�</nowiki>) ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse(<nowiki>�</nowiki>Points.xmf<nowiki>�</nowiki>) ge = dom.FindElementByPath(<nowiki>�</nowiki>/Xdmf/Domain/Grid<nowiki>�</nowiki>) grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print <nowiki>�</nowiki>Values = <nowiki>�</nowiki>, conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print <nowiki>�</nowiki>Geo Type = <nowiki>�</nowiki>, geo.GetGeometryTypeAsString(), <nowiki>�</nowiki> <nowiki>#</nowiki> Points = <nowiki>�</nowiki>, geo.GetNumberOfPoints() print <nowiki>�</nowiki>Points = <nowiki>�</nowiki>, points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api can get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can root.Build() <nowiki>#</nowiki> Information i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure <nowiki>#</nowiki> Insert() creates an XML node and inserts it under <nowiki>#</nowiki> the parent <nowiki>#</nowiki> Domain dm = XdmfDomain() root.Insert(dm) <nowiki>#</nowiki> Grid g = XdmfGrid() g.SetName("Structured Grid") <nowiki>#</nowiki> Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString(<nowiki>�</nowiki>10 20 30<nowiki>�</nowiki>) <nowiki>#</nowiki> Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) <nowiki>#</nowiki> Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) <nowiki>#</nowiki> Update XML and Write Values to DataItems root.Build() <nowiki>#</nowiki> DataItems &gt; 100 values are heavy print d.Serialize() <nowiki>#</nowiki> prints to stdout d.Write(<nowiki>�</nowiki>MyMesh.xmf<nowiki>�</nowiki>) <nowiki>#</nowiki> write to file e3eb8b2abdfe77d1a53e0bbd58d6c7edad8eb6cd 14 13 2007-05-03T16:30:38Z 128.63.127.201 0 wikitext text/x-wiki '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the se functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parser strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki></nowiki>MyXMLFile.xmf<nowiki></nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel ow a parent node : XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet(<nowiki></nowiki>Domain<nowiki></nowiki>) <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement(<nowiki></nowiki>Grid<nowiki></nowiki>, 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>) SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki></nowiki>Grid<nowiki></nowiki>) Status = XdmfDOM.Set(SubGrid, <nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My SubGrid<nowiki></nowiki>) And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write(<nowiki></nowiki>MyFile.xmf<nowiki></nowiki>) '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>) For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set(<nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My Grid<nowiki></nowiki>) Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz-&gt;SetNumberType(XDMF_FLOAT64_TYPE) xyz-&gt;SetShape(3, dims); // KDim, JDim, IDim xyz-&gt;SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz-&gt;SetValues(1, y, total, 3, 1); xyz-&gt;SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import <nowiki>*</nowiki> def Expression(<nowiki>*</nowiki>args) : e = <nowiki></nowiki><nowiki></nowiki> for arg in args : if hasattr(arg, <nowiki></nowiki>GetTagName<nowiki></nowiki>) : e += arg.GetTagName() + <nowiki></nowiki> <nowiki></nowiki> else : e += arg + <nowiki></nowiki> <nowiki></nowiki> return XdmfExpr(e) if __name__ == <nowiki></nowiki>__main__<nowiki></nowiki> : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print <nowiki></nowiki>a1 Values = <nowiki></nowiki>, a1.GetValues() print <nowiki></nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki> 2:10 <nowiki>] </nowiki><nowiki></nowiki>).GetValues() print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues() print <nowiki></nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki><nowiki></nowiki>, a2, <nowiki></nowiki><nowiki>]</nowiki><nowiki></no wiki>).GetValues() print <nowiki></nowiki>a1 + a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> + <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> <nowiki>*</nowiki> <nowiki></nowiki>, a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues() print <nowiki></nowiki>a1 , a2 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>a1 , a2, a1 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2, <nowiki></nowiki> , <nowiki></nowiki>, a1).GetValues() print <nowiki></nowiki>a1 ; a2 (Concat) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> ; <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>where(a1 &gt; 10) = <nowiki></nowiki> + Expression(<nowiki></nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10)<nowiki></nowiki>).GetValues() print <nowiki></nowiki>a2<nowiki>[</nowiki>where(a1 &gt; 10)<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a2, <nowiki></nowiki><nowiki>[</nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10 )<nowiki>]</nowiki><nowiki></nowiki>).GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfHDF''' In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = <nowiki></nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = <nowiki></nowiki>3 2 5 1 . Values = <nowiki></nowiki>100 200 300 .. <nowiki>#</nowiki> Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) <nowiki>#</nowiki> Open for Writing. This will truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Geometry<nowiki></nowiki>, <nowiki></nowiki>w<nowiki></nowiki>) H5.Write(GeometryArray) H5.Close() <nowiki>#</nowiki> Connectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) <nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Connectivity<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) H5.Write(ConnectivityArray) H5.Close() <nowiki>#</nowiki> Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) <nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse(<nowiki></nowiki>Points.xmf<nowiki></nowiki>) ge = dom.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki></nowiki>) grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print <nowiki></nowiki>Values = <nowiki></nowiki>, conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print <nowiki></nowiki>Geo Type = <nowiki></nowiki>, geo.GetGeometryTypeAsString(), <nowiki></nowiki> <nowiki>#</nowiki> Points = <nowiki></nowiki>, geo.GetNumberOfPoints() print <nowiki></nowiki>Points = <nowiki></nowiki>, points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work rec ursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can root.Build() <nowiki>#</nowiki> Information i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure <nowiki>#</nowiki> Insert() creates an XML node and inserts it under <nowiki>#</nowiki> the parent <nowiki>#</nowiki> Domain dm = XdmfDomain() root.Insert(dm) <nowiki>#</nowiki> Grid g = XdmfGrid() g.SetName("Structured Grid") <nowiki>#</nowiki> Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString(<nowiki></nowiki>10 20 30<nowiki></nowiki>) <nowiki>#</nowiki> Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) <nowiki>#</nowiki> Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) <nowiki>#</nowiki> Update XML and Write Values to DataItems root.Build() <nowiki>#</nowiki> DataItems &gt; 100 values are heavy print d.Serialize() <nowiki>#</nowiki> prints to stdout d.Write(<nowiki></nowiki>MyMesh.xmf<nowiki></nowiki>) <nowiki>#</nowiki> write to file 6f1614df052fb3ca7b7c6991107e6e6ba33a8e82 15 14 2007-05-03T16:31:41Z 128.63.127.201 0 wikitext text/x-wiki '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the se functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parser strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki></nowiki>MyXMLFile.xmf<nowiki></nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel ow a parent node : XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet(<nowiki></nowiki>Domain<nowiki></nowiki>) <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement(<nowiki></nowiki>Grid<nowiki></nowiki>, 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>) SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki></nowiki>Grid<nowiki></nowiki>) Status = XdmfDOM.Set(SubGrid, <nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My SubGrid<nowiki></nowiki>) And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write(<nowiki></nowiki>MyFile.xmf<nowiki></nowiki>) '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>) For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set(<nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My Grid<nowiki></nowiki>) Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz-&gt;SetNumberType(XDMF_FLOAT64_TYPE) xyz-&gt;SetShape(3, dims); // KDim, JDim, IDim xyz-&gt;SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz-&gt;SetValues(1, y, total, 3, 1); xyz-&gt;SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import <nowiki>*</nowiki> def Expression(<nowiki>*</nowiki>args) : e = <nowiki></nowiki><nowiki></nowiki> for arg in args : if hasattr(arg, <nowiki></nowiki>GetTagName<nowiki></nowiki>) : e += arg.GetTagName() + <nowiki></nowiki> <nowiki></nowiki> else : e += arg + <nowiki></nowiki> <nowiki></nowiki> return XdmfExpr(e) if __name__ == <nowiki></nowiki>__main__<nowiki></nowiki> : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print <nowiki></nowiki>a1 Values = <nowiki></nowiki>, a1.GetValues() print <nowiki></nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki> 2:10 <nowiki>] </nowiki><nowiki></nowiki>).GetValues() print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues() print <nowiki></nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki><nowiki></nowiki>, a2, <nowiki></nowiki><nowiki>]</nowiki><nowiki></no wiki>).GetValues() print <nowiki></nowiki>a1 + a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> + <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> <nowiki>*</nowiki> <nowiki></nowiki>, a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues() print <nowiki></nowiki>a1 , a2 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>a1 , a2, a1 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2, <nowiki></nowiki> , <nowiki></nowiki>, a1).GetValues() print <nowiki></nowiki>a1 ; a2 (Concat) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> ; <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>where(a1 &gt; 10) = <nowiki></nowiki> + Expression(<nowiki></nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10)<nowiki></nowiki>).GetValues() print <nowiki></nowiki>a2<nowiki>[</nowiki>where(a1 &gt; 10)<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a2, <nowiki></nowiki><nowiki>[</nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10 )<nowiki>]</nowiki><nowiki></nowiki>).GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfHDF''' In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = <nowiki></nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = <nowiki></nowiki>3 2 5 1 . Values = <nowiki></nowiki>100 200 300 .. <nowiki>#</nowiki> Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) <nowiki>#</nowiki> Open for Writing. This will truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Geometry<nowiki></nowiki>, <nowiki></nowiki>w<nowiki></nowiki>) H5.Write(GeometryArray) H5.Close() <nowiki>#</nowiki> Connectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) <nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Connectivity<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) H5.Write(ConnectivityArray) H5.Close() <nowiki>#</nowiki> Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) <nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse(<nowiki></nowiki>Points.xmf<nowiki></nowiki>) ge = dom.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki></nowiki>) grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print <nowiki></nowiki>Values = <nowiki></nowiki>, conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print <nowiki></nowiki>Geo Type = <nowiki></nowiki>, geo.GetGeometryTypeAsString(), <nowiki></nowiki> <nowiki>#</nowiki> Points = <nowiki></nowiki>, geo.GetNumberOfPoints() print <nowiki></nowiki>Points = <nowiki></nowiki>, points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work rec ursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can root.Build() <nowiki>#</nowiki> Information i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure <nowiki>#</nowiki> Insert() creates an XML node and inserts it under <nowiki>#</nowiki> the parent <nowiki>#</nowiki> Domain dm = XdmfDomain() root.Insert(dm) <nowiki>#</nowiki> Grid g = XdmfGrid() g.SetName("Structured Grid") <nowiki>#</nowiki> Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString(<nowiki></nowiki>10 20 30<nowiki></nowiki>) <nowiki>#</nowiki> Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) <nowiki>#</nowiki> Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() <nowiki>#</nowiki> DataItems &gt; 100 values are heavy print d.Serialize() <nowiki>#</nowiki> prints to stdout d.Write(<nowiki></nowiki>MyMesh.xmf<nowiki></nowiki>) <nowiki>#</nowiki> write to file eeca8af04dcfd9bbb81ec300d04e251969008f43 22 15 2007-05-03T17:35:04Z 128.63.127.211 0 wikitext text/x-wiki '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the se functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parser strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel ow a parent node : XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet(<nowiki></nowiki>Domain<nowiki></nowiki>) <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement(<nowiki></nowiki>Grid<nowiki></nowiki>, 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>) SubGrid = XdmfDOM.InsertNew(GridNode, <nowiki></nowiki>Grid<nowiki></nowiki>) Status = XdmfDOM.Set(SubGrid, <nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My SubGrid<nowiki></nowiki>) And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write(<nowiki></nowiki>MyFile.xmf<nowiki></nowiki>) '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki>[</nowiki>3<nowiki>]</nowiki><nowiki></nowiki>) Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, <nowiki></nowiki>Name<nowiki></nowiki>) For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set(<nowiki></nowiki>Name<nowiki></nowiki>, <nowiki></nowiki>My Grid<nowiki></nowiki>) Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz-&gt;SetNumberType(XDMF_FLOAT64_TYPE) xyz-&gt;SetShape(3, dims); // KDim, JDim, IDim xyz-&gt;SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz-&gt;SetValues(1, y, total, 3, 1); xyz-&gt;SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import <nowiki>*</nowiki> def Expression(<nowiki>*</nowiki>args) : e = <nowiki></nowiki><nowiki></nowiki> for arg in args : if hasattr(arg, <nowiki></nowiki>GetTagName<nowiki></nowiki>) : e += arg.GetTagName() + <nowiki></nowiki> <nowiki></nowiki> else : e += arg + <nowiki></nowiki> <nowiki></nowiki> return XdmfExpr(e) if __name__ == <nowiki></nowiki>__main__<nowiki></nowiki> : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print <nowiki></nowiki>a1 Values = <nowiki></nowiki>, a1.GetValues() print <nowiki></nowiki>a1<nowiki>[</nowiki>2:10<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki> 2:10 <nowiki>] </nowiki><nowiki></nowiki>).GetValues() print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues() print <nowiki></nowiki>a1<nowiki>[</nowiki>a2<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki><nowiki>[</nowiki><nowiki></nowiki>, a2, <nowiki></nowiki><nowiki>]</nowiki><nowiki></no wiki>).GetValues() print <nowiki></nowiki>a1 + a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> + <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>a1 <nowiki>*</nowiki> a2 = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> <nowiki>*</nowiki> <nowiki></nowiki>, a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print <nowiki></nowiki>a2 Values = <nowiki></nowiki>, a2.GetValues() print <nowiki></nowiki>a1 , a2 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>a1 , a2, a1 (Interlace) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> , <nowiki></nowiki>, a2, <nowiki></nowiki> , <nowiki></nowiki>, a1).GetValues() print <nowiki></nowiki>a1 ; a2 (Concat) = <nowiki></nowiki> + Expression(a1 , <nowiki></nowiki> ; <nowiki></nowiki>, a2).GetValues() print <nowiki></nowiki>where(a1 &gt; 10) = <nowiki></nowiki> + Expression(<nowiki></nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10)<nowiki></nowiki>).GetValues() print <nowiki></nowiki>a2<nowiki>[</nowiki>where(a1 &gt; 10)<nowiki>]</nowiki> = <nowiki></nowiki> + Expression(a2, <nowiki></nowiki><nowiki>[</nowiki>Where( <nowiki></nowiki>, a1 , <nowiki></nowiki> &gt; 10 )<nowiki>]</nowiki><nowiki></nowiki>).GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfHDF''' In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = <nowiki></nowiki>-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = <nowiki></nowiki>3 2 5 1 . Values = <nowiki></nowiki>100 200 300 .. <nowiki>#</nowiki> Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) <nowiki>#</nowiki> Open for Writing. This will truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Geometry<nowiki></nowiki>, <nowiki></nowiki>w<nowiki></nowiki>) H5.Write(GeometryArray) H5.Close() <nowiki>#</nowiki> Connectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) <nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Connectivity<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) H5.Write(ConnectivityArray) H5.Close() <nowiki>#</nowiki> Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) <nowiki>#</nowiki> Open for Reading and Writing. This will NOT truncate the file. H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open(<nowiki></nowiki>Example1.h5:/Values<nowiki></nowiki>, <nowiki></nowiki>rw<nowiki></nowiki>) ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse(<nowiki></nowiki>Points.xmf<nowiki></nowiki>) ge = dom.FindElementByPath(<nowiki></nowiki>/Xdmf/Domain/Grid<nowiki></nowiki>) grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print <nowiki></nowiki>Values = <nowiki></nowiki>, conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print <nowiki></nowiki>Geo Type = <nowiki></nowiki>, geo.GetGeometryTypeAsString(), <nowiki></nowiki> <nowiki>#</nowiki> Points = <nowiki></nowiki>, geo.GetNumberOfPoints() print <nowiki></nowiki>Points = <nowiki></nowiki>, points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work rec ursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) <nowiki>#</nowiki> Change the Version number because we can root.Build() <nowiki>#</nowiki> Information i = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) <nowiki>#</nowiki> XML DOM is used as the keeper of the structure <nowiki>#</nowiki> Insert() creates an XML node and inserts it under <nowiki>#</nowiki> the parent <nowiki>#</nowiki> Domain dm = XdmfDomain() root.Insert(dm) <nowiki>#</nowiki> Grid g = XdmfGrid() g.SetName("Structured Grid") <nowiki>#</nowiki> Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString(<nowiki></nowiki>10 20 30<nowiki></nowiki>) <nowiki>#</nowiki> Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) <nowiki>#</nowiki> Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() <nowiki>#</nowiki> DataItems &gt; 100 values are heavy print d.Serialize() <nowiki>#</nowiki> prints to stdout d.Write(<nowiki></nowiki>MyMesh.xmf<nowiki></nowiki>) <nowiki>#</nowiki> write to file 083d1bddeaeadfba5d7e641f098b7eb95d34214a 23 22 2007-05-03T17:55:49Z 128.63.127.211 0 wikitext text/x-wiki '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the se functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parser strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel ow a parent node : XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float <nowiki>*</nowiki>x, <nowiki>*</nowiki>y, <nowiki>*</nowiki>z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz-&gt;SetNumberType(XDMF_FLOAT64_TYPE) xyz-&gt;SetShape(3, dims); // KDim, JDim, IDim xyz-&gt;SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz-&gt;SetValues(1, y, total, 3, 1); xyz-&gt;SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfHDF''' In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Values ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file d3ea8f823282597dfea7fb55686cd76630fae3e9 24 23 2007-05-03T18:06:56Z Jerry 2 wikitext text/x-wiki '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the se functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parser strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel ow a parent node : XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfHDF''' In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file 535cb1be8240b1e6affd9a29307a49f56251d182 31 24 2007-05-03T21:33:07Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform the se functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Mod el (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parser strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element bel ow a parent node : XdmfXmlNode FindElement (XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the 3^rd^ Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki></nowiki>Name<nowiki></nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfHDF''' In XDMF Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file c4c16d1f7956f8e7415942a799c80eff6eadf373 42 31 2007-12-11T15:39:11Z Dave.demarle 5 fix typos wikitext text/x-wiki [[Image:XdmfLogo1.gif]] '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parse strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement ( XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1 ) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfHDF''' In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file 061c418d8fb4fa80c594b4c01721814e91b86a5c 44 42 2008-02-01T15:04:03Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parse strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement ( XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1 ) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfTime''' When UpdateInformation() gets called for a Grid, an XdmfTime object is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there is a &lt;Time&gt; element in the Grid the object is populated. If the Grid is Non-Uniform (i.e. Collection, Tree), the children are updated as well. If the parent is TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the appropriate value set. Methods : XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0) This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten. XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax) this checks to see if the Time is entirely in Min/Max. Since this is a float comparison, I added an Epsilon member to XdmfTime with default value = 1e-7. This may be changed via XdmfTime::SetEpsilon() XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill) This populates the array with the direct children that are entirely in min/max. For example if the range is 0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL. '''XdmfHDF''' In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) # If an array is given a HeavyDataSetName, that is # where it will be written p.setHeavyDataSetName('MyData.h5:/Pressure') g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file 931a0839a748265cdf910d113e4825a96a2f3343 File:XdmfLogo.gif 6 4 25 2007-05-03T21:16:32Z Jerry 2 Try a Logo wikitext text/x-wiki Try a Logo a35ab1b3e3d2e8a45a7e7ebf6009b93a1fe6fae3 File:XdmfLogo1.gif 6 5 26 2007-05-03T21:20:54Z Jerry 2 Smaller Logo wikitext text/x-wiki Smaller Logo 17e4dd8f7ee44fae32a05b32f213c8b2b55e11b8 Get Xdmf original 0 6 34 2007-05-04T13:32:31Z Jerry 2 New page: == '''Obtaining and Installing XDMF''' == The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, ... wikitext text/x-wiki == '''Obtaining and Installing XDMF''' == The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, on the HPC systems at the ARL MSRC. If you need access on other platforms, obtain the source via CVS and follow the installation instructions. XDMF has been built and tested on a variety of UNIX platforms and on Win32 and Cygwin. CVS Access to the XDMF Source Code Repository XDMF is obtained via CVS access to the XDMF source code repository as a user (anonymous, read-only access). One of the advantages of CVS access is that you can incrementally update your repository without having to retrieve the entire source distribution. The following assumes that you have a basic knowledge of CVS. Anonymous User Read-Only Access You can obtain read-only access to the CVS repository as follows. cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login (respond with password xdmf) Follow this command by checking out the source code: cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf This CVS tree is Xdmf. Checkout the CVS in a clean directory as it will create an Xdmf directory and possibly overwrite an existing Xdmf tree. You will also need CMake which is a new cross platform build tool. '''Installation''' XDMF depends on Expat and HDF5. While a version of Expat and HDF5 comes with the the XDMF source, you might want to get the latest version of these packages. Obtain Expat from here . Obtain HDF from here. You'll also want Python (version 2.5 or later). Obtain Python from [http://www.python.org Python.Org]. If you want to use the scientific visualization tools, you'll need vtk ( version 5.0 or later ). Obtain vtk from [http://public.kitware.com Kitware.Com]. Xdmf uses CMake for installation. Pre-Built binaries of CMake are available for many platforms, or you can install from source. The advantage of CMake is that it provides a consistent build system for UNIX and Win32. For this reason, we replaced the previous autoconf (./configure �prefix �) method with CMake. Once you�ve installed the necessary support packages, begin to build Xdmf for your platform. For example, suppose you wish to build a Linux version : # mkdir MyXdmf # cd MyXdmf # cvs <nowiki>-d ...</nowiki> login # cvs <nowiki>-d ...</nowiki> co Xdmf This creates an Xdmf directory of the source code # mkdir Linux # cd Linux # cmake ../Xdmf CMake comes with several different commands. The two most important are cmake (the command line version) and ccmake (a curses based gui version). Both versions create a Makefile in the current directory and a file ''CMakeCache.txt'' that contains the compile time options. Options include things like additional compiler flags, where to find various packages (like HDF and expat), and which parts to build ( shared objects, python interface, etc.). As you change the CMakeCache.txt file either by hand or via the gui, additional options may appear. For example, if you decide to build the Python interface, new options for the location of Python include files and libraries will appear in the CMakeCache.txt file after you re-run cmake. In short, you run cmake, change CMakeCache.txt, and re-run cmake until you have the configuration you want. CMake is fairly sophisticated and can make reasonable guesses for many of the options. Once this configuration process is complete, run ''make'' and the appropriate binaries will be built in the directory MyXdmf/Linux/bin. For each architecture, create a new directory and repeat the process. This allows you to keep all platforms synchronized to the same source code base.Depending on the configuration you will see the following files : * libXdmf.[a so dll] C++ class library for XDMF * _Xdmf.[so dll] Python interface * libXdmfTCL.[so dll] Tcl interface * XdmfFormatExample Executable to write/read XDMF file The Python interface has been built with the �shadow classes�. This means that accessing XDMF via Python done in an Object Oriented manner just like in C++. To use the Object Oriented interface, you need to copy Xdmf.py ( found in �/Xdmf/python) somewhere in your Python path. dfad60182082cf30233da703db09b59a3732b49c 35 34 2007-05-04T13:48:00Z Jerry 2 wikitext text/x-wiki == '''Obtaining and Installing XDMF''' == The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, on the HPC systems at the ARL MSRC. If you need access on other platforms, obtain the source via CVS and follow the installation instructions. XDMF has been built and tested on a variety of UNIX platforms and on Win32 and Cygwin. CVS Access to the XDMF Source Code Repository XDMF is obtained via CVS access to the XDMF source code repository as a user (anonymous, read-only access). One of the advantages of CVS access is that you can incrementally update your repository without having to retrieve the entire source distribution. The following assumes that you have a basic knowledge of CVS. Anonymous User Read-Only Access You can obtain read-only access to the CVS repository as follows. cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login (respond with password xdmf) Follow this command by checking out the source code: cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf This CVS tree is Xdmf. Checkout the CVS in a clean directory as it will create an Xdmf directory and possibly overwrite an existing Xdmf tree. You will also need CMake which is a new cross platform build tool. '''Installation''' XDMF depends on Expat and HDF5. While a version of Expat and HDF5 comes with the the XDMF source, you might want to get the latest version of these packages. Obtain Expat from here . Obtain HDF from here. You'll also want Python (version 2.5 or later). Obtain Python from [http://www.python.org Python.Org]. If you want to use the scientific visualization tools, you'll need vtk ( version 5.0 or later ). Obtain vtk from [http://public.kitware.com Kitware.Com]. Xdmf uses CMake for installation. Pre-Built binaries of CMake are available for many platforms, or you can install from source. The advantage of CMake is that it provides a consistent build system for UNIX and Win32. For this reason, we replaced the previous autoconf <nowiki>(./configure --prefix...)</nowiki> method with CMake. Once you�ve installed the necessary support packages, begin to build Xdmf for your platform. For example, suppose you wish to build a Linux version : # mkdir MyXdmf # cd MyXdmf # cvs <nowiki>-d ...</nowiki> login # cvs <nowiki>-d ...</nowiki> co Xdmf This creates an Xdmf directory of the source code # mkdir Linux # cd Linux # cmake ../Xdmf CMake comes with several different commands. The two most important are cmake (the command line version) and ccmake (a curses based gui version). Both versions create a Makefile in the current directory and a file ''CMakeCache.txt'' that contains the compile time options. Options include things like additional compiler flags, where to find various packages (like HDF and expat), and which parts to build ( shared objects, python interface, etc.). As you change the CMakeCache.txt file either by hand or via the gui, additional options may appear. For example, if you decide to build the Python interface, new options for the location of Python include files and libraries will appear in the CMakeCache.txt file after you re-run cmake. In short, you run cmake, change CMakeCache.txt, and re-run cmake until you have the configuration you want. CMake is fairly sophisticated and can make reasonable guesses for many of the options. Once this configuration process is complete, run ''make'' and the appropriate binaries will be built in the directory MyXdmf/Linux/bin. For each architecture, create a new directory and repeat the process. This allows you to keep all platforms synchronized to the same source code base.Depending on the configuration you will see the following files : * libXdmf.[a so dll] C++ class library for XDMF * _Xdmf.[so dll] Python interface * libXdmfTCL.[so dll] Tcl interface * XdmfFormatExample Executable to write/read XDMF file The Python interface has been built with the shadow classes. This means that accessing XDMF via Python done in an Object Oriented manner just like in C++. To use the Object Oriented interface, you need to copy Xdmf.py ( found in <nowiki>.../Xdmf/libsrc/Xdmf.py</nowiki>) somewhere in your Python path. 1f7090badf41e85866502c62d76aa63a72888040 File:TwoHex.jpg 6 7 37 2007-05-04T14:41:35Z Jerry 2 Two Hexahedron from ParaView wikitext text/x-wiki Two Hexahedron from ParaView fa19c3f070231906fb2aa9b7971a44277b72260d Read Xdmf 0 8 38 2007-05-04T15:35:45Z Jerry 2 New page: == Reading XDMF Data == [[Image:TwoHex.jpg]] The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face. There are values centered a... wikitext text/x-wiki == Reading XDMF Data == [[Image:TwoHex.jpg]] The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face. There are values centered at the nodes and at the cell centers. The values for geometry, connectivity, and scalars are all stored directly in the XML file. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf> <Domain> <Grid Name="TestGrid"> <Topology Type="Hexahedron" NumberOfElements="2" > <DataItem Format="XML" DataType="Float" Dimensions="2 8"> 0 1 7 6 3 4 10 9 1 2 8 7 4 5 11 10 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="4 3 3"> 0.0 0.0 1.0 1.0 0.0 1.0 3.0 0.0 2.0 0.0 1.0 1.0 1.0 1.0 1.0 3.0 2.0 2.0 0.0 0.0 -1.0 1.0 0.0 -1.0 3.0 0.0 -2.0 0.0 1.0 -1.0 1.0 1.0 -1.0 3.0 2.0 -2.0 </DataItem> </Geometry> <Attribute Name="NodeValues" Center="Node"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="4 3" > 100 200 300 300 400 500 300 400 500 500 600 700 </DataItem> </Attribute> <Attribute Name="CellValues" Center="Cell"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="2" > 100 200 </DataItem> </Attribute> </Grid> </Domain> </Xdmf> The XML is stored in the file "MyGrid.xmf". The following Python program demonstrated parsing the XML and retrieving the data values. from Xdmf import * dom = XdmfDOM() dom.Parse('MyGrid.xmf') # We now have a tree. Find the one and only Grid element ge = dom.FindElementByPath('/Xdmf/Domain/Grid') grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) # Read Light Data grid.UpdateInformation() # Read Heavy Data which includes Topology and Geometry grid.Update() top = grid.GetTopology() conn = top.GetConnectivity() print 'Values = ', conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print 'Geo Type = ', geo.GetGeometryTypeAsString(), ' # Points = ', geo.GetNumberOfPoints() print 'Points = ', points.GetValues() # for each Attribute, print Light Data and Values for i in range(grid.GetNumberOfAttributes()) : attr = grid.GetAttribute(i) print 'Attribute ', i, ' Name = ', attr.Get('Name') # Attribute HeavyData is not Updated by default # there could potentially be many causing huge IO attr.Update() vals = attr.GetValues() print 'Values ', vals.GetValues() 98255db3b4b8800f785d362434a2cb0580fa134c Write Xdmf 0 9 39 2007-05-04T16:17:53Z Jerry 2 New page: == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provi... wikitext text/x-wiki == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="Time" Value="0.0123"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> ~ fccd8c7391a9bf679fcb48bdc9105c277b5864a7 49 39 2008-05-02T19:36:20Z Jerry 2 wikitext text/x-wiki == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> ~ 69cb45c583aee33a5a93361b2ba0a5b1bbed6eac Write from Fortran 0 10 47 2008-05-02T16:32:03Z Jerry 2 New page: == Writing Xdmf from Fortran == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, h... wikitext text/x-wiki == Writing Xdmf from Fortran == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider the following Fortran program which build a grid of Hexahedra with some node and cell centered values : CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Grid of Hexahedron Centered at 0,0,0 C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN ) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) INTEGER I, J, K, IDX REAL*8 X, Y, Z, DX, DY, DZ C Print *, 'Size = ', IDIM, JDIM, KDIM PRINT *, 'Initialze Problem' C XYZ Values of Nodes C From -1 to 1 DX = 2.0 / ( IDIM - 1 ) DY = 2.0 / ( JDIM - 1 ) DZ = 2.0 / ( KDIM - 1 ) Z = -1.0 DO 112 K= 1, KDIM Y = -1.0 DO 111 J= 1, JDIM X = -1.0 DO 110 I= 1, IDIM XYZ( 1, I, J, K ) = X XYZ( 2, I, J, K ) = Y XYZ( 3, I, J, K ) = Z X = X + DX 110 CONTINUE Y = Y + DY 111 CONTINUE Z = Z + DZ 112 CONTINUE C Connections IDX = 1 DO 122 K= 0, KDIM - 2 DO 121 J= 0, JDIM - 2 DO 120 I= 1, IDIM - 1 ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I IDX = IDX + 1 120 CONTINUE 121 CONTINUE 122 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Node Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) INTEGER I, J, K REAL*8 X, Y, Z PRINT *, 'Calculating Node Centered Data' DO 212, K=1, KDIM DO 211, J=1, JDIM DO 210, I=1, IDIM X = XYZ( 1, I, J, K ) Y = XYZ( 2, I, J, K ) Z = XYZ( 3, I, J, K ) NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z )) 210 CONTINUE 211 CONTINUE 212 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Cell Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) INTEGER IDIM, JDIM, KDIM, ITER, KICKER REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) INTEGER I, J, K PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER DO 312, K=1, KDIM - 1 DO 311, J=1, JDIM - 1 DO 310, I=1, IDIM - 1 X = XYZ( 1, I, J, K ) CCVALUES( I, J, K ) = C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) / C EXP( X / ( 1.0 * ITER ) ) 310 CONTINUE 311 CONTINUE 312 CONTINUE C Waste Time DO 313 I=1, 1000000 X = 0.1 * ITER / I Y = SQRT( X * X ) Z = EXP( Y ) 313 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Main Program : C Initialize Grid C Initialize Node Centered Data C For Iteration = 1 to 10 C Generate Cell Centered Data C Done C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC PROGRAM HexMesh PARAMETER ( IDIM = 11 ) PARAMETER ( JDIM = 13 ) PARAMETER ( KDIM = 15 ) REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) C REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) C INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) C INTEGER ITER, KICKER, NITER, NARG INTEGER IUNIT CHARACTER*80 ARGIN C NARG = IARGC() IF( NARG .GE. 1 ) THEN CALL GETARG( 1, ARGIN ) READ( ARGIN, '(I)') NITER ELSE NITER = 10 ENDIF CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN ) CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) C IUNIT = 14 OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) IDIM * JDIM * KDIM WRITE ( IUNIT, * ) XYZ CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) WRITE ( IUNIT, * ) ICONN CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) NCVALUES CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' ) REWIND IUNIT C KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML via print statements (we could also shove bamboo shoots under our fingernails). A better approach would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary Xdmf calls to produce valid Xdmf XML and HDF5 files : #include <Xdmf.h> // We want the filenames to be based on the iteration // and padded with zeros using std::setw; using std::setfill; // This works with g77. Different compilers require different // name mangling. '''#define XdmfWrite xdmfwrite_''' // // C/C++ expect NULL terminated strings. Here is a conversion subroutine. char * DemoConvertFortranString( char *FtnName ) { static char Name[80]; char *np; memcpy(Name, FtnName, 79 ); Name[79] = '\0'; np = &Name[78]; while( ( np > Name ) && ( *np <= ' ') ) { np--; } *np = '\0'; return( Name ); } // // C++ will mangle the name based on the argument list. This tells the // compiler not to mangle the name so we can call it from 'C' (but // really Fortran in this case) // extern "C" { // void '''XdmfWrite(''' char *FtnName, int *Iteration, int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points, XdmfInt32 *Conns, XdmfFloat64 *NodeData, XdmfFloat64 *CellData){ char *Name; char FullName[80]; ostrstream DataName(FullName, 80); XdmfDOM dom; XdmfRoot root; XdmfDomain domain; XdmfGrid grid; XdmfTime time; XdmfTopology *topology; XdmfGeometry *geometry; XdmfAttribute nodedata; XdmfAttribute celldata; XdmfArray *array; // Name = DemoConvertFortranString( FtnName ); // root.SetDOM(&dom); root.SetVersion(2.0); root.Build(); // Domain root.Insert(&domain); // Grid grid.SetName("Demonstration Grid"); domain.Insert(&grid); time.SetTimeType(XDMF_TIME_SINGLE); time.SetValue(0.001 * *Iteration); grid.Insert(&time); // Topology topology = grid.GetTopology(); topology->SetTopologyType(XDMF_HEX); topology->SetNumberOfElements(*NumberOfHex); // Fortran is 1 based while c++ is 0 based so // Either subtract 1 from all connections or specify a BaseOffset topology->SetBaseOffset(1); // If you haven't assigned an XdmfArray, GetConnectivity() will create one. array = topology->GetConnectivity(); array->SetNumberOfElements(*NumberOfHex * 8); array->SetValues(0, Conns, *NumberOfHex * 8); // C++ string hocus pocus. // We're actually building the string in FullName[] but were using streams. // the DatasetName will be Demo_00001.h5:/Conns. DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends; // Where the data will actually be written array->SetHeavyDataSetName(FullName); // Geometry geometry = grid.GetGeometry(); geometry->SetGeometryType(XDMF_GEOMETRY_XYZ); geometry->SetNumberOfPoints(*NumberOfPoints); array = geometry->GetPoints(); array->SetValues(0, Points, *NumberOfPoints * 3); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends; array->SetHeavyDataSetName(FullName); // Node Data nodedata.SetName("Node Scalar"); nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = nodedata.GetValues(); array->SetNumberOfElements(*NumberOfPoints); array->SetValues(0, NodeData, *NumberOfPoints); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends; array->SetHeavyDataSetName(FullName); // Cell Data celldata.SetName("Cell Scalar"); celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = celldata.GetValues(); array->SetNumberOfElements(*NumberOfHex); array->SetValues(0, CellData, *NumberOfHex); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends; array->SetHeavyDataSetName(FullName); // Attach and Write grid.Insert(&nodedata); grid.Insert(&celldata); // Build is recursive ... it will be called on all of the child nodes. // This updates the DOM and writes the HDF5 root.Build(); // Write the XML DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends; dom.Write(FullName); } } Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()''' Original : KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Modified : INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) INPNT = IDIM * JDIM * KDIM KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES '''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)''' 1000 CONTINUE CLOSE ( IUNIT ) C END Now the program produces one HDF5 file and one XML file for each iteration. The final step would be to group all of these together so we could animate them over time. Instead of duplicating the XML in another file for each grid, we can use a little XML magic to pull them together : <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0"> <Domain> <Grid GridType="Collection" CollectionType="Temporal"> <xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> </Grid> </Domain> </Xdmf> This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists of the first (in our case, the only) grid in each file. 1f513ba184c9707c9787ab2640fd0d4716ff432c 48 47 2008-05-02T16:35:05Z Jerry 2 wikitext text/x-wiki == Writing Xdmf from Fortran == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider the following Fortran program which build a grid of Hexahedra with some node and cell centered values : CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Grid of Hexahedron Centered at 0,0,0 C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN ) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) INTEGER I, J, K, IDX REAL*8 X, Y, Z, DX, DY, DZ C Print *, 'Size = ', IDIM, JDIM, KDIM PRINT *, 'Initialze Problem' C XYZ Values of Nodes C From -1 to 1 DX = 2.0 / ( IDIM - 1 ) DY = 2.0 / ( JDIM - 1 ) DZ = 2.0 / ( KDIM - 1 ) Z = -1.0 DO 112 K= 1, KDIM Y = -1.0 DO 111 J= 1, JDIM X = -1.0 DO 110 I= 1, IDIM XYZ( 1, I, J, K ) = X XYZ( 2, I, J, K ) = Y XYZ( 3, I, J, K ) = Z X = X + DX 110 CONTINUE Y = Y + DY 111 CONTINUE Z = Z + DZ 112 CONTINUE C Connections IDX = 1 DO 122 K= 0, KDIM - 2 DO 121 J= 0, JDIM - 2 DO 120 I= 1, IDIM - 1 ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I IDX = IDX + 1 120 CONTINUE 121 CONTINUE 122 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Node Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) INTEGER I, J, K REAL*8 X, Y, Z PRINT *, 'Calculating Node Centered Data' DO 212, K=1, KDIM DO 211, J=1, JDIM DO 210, I=1, IDIM X = XYZ( 1, I, J, K ) Y = XYZ( 2, I, J, K ) Z = XYZ( 3, I, J, K ) NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z )) 210 CONTINUE 211 CONTINUE 212 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Cell Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) INTEGER IDIM, JDIM, KDIM, ITER, KICKER REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) INTEGER I, J, K PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER DO 312, K=1, KDIM - 1 DO 311, J=1, JDIM - 1 DO 310, I=1, IDIM - 1 X = XYZ( 1, I, J, K ) CCVALUES( I, J, K ) = C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) / C EXP( X / ( 1.0 * ITER ) ) 310 CONTINUE 311 CONTINUE 312 CONTINUE C Waste Time DO 313 I=1, 1000000 X = 0.1 * ITER / I Y = SQRT( X * X ) Z = EXP( Y ) 313 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Main Program : C Initialize Grid C Initialize Node Centered Data C For Iteration = 1 to 10 C Generate Cell Centered Data C Done C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC PROGRAM HexMesh PARAMETER ( IDIM = 11 ) PARAMETER ( JDIM = 13 ) PARAMETER ( KDIM = 15 ) REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) C REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) C INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) C INTEGER ITER, KICKER, NITER, NARG INTEGER IUNIT CHARACTER*80 ARGIN C NARG = IARGC() IF( NARG .GE. 1 ) THEN CALL GETARG( 1, ARGIN ) READ( ARGIN, '(I)') NITER ELSE NITER = 10 ENDIF CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN ) CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) C IUNIT = 14 OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) IDIM * JDIM * KDIM WRITE ( IUNIT, * ) XYZ CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) WRITE ( IUNIT, * ) ICONN CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) NCVALUES CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' ) REWIND IUNIT C KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML via print statements (we could also shove bamboo shoots under our fingernails). A better approach would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary Xdmf calls to produce valid Xdmf XML and HDF5 files : #include <Xdmf.h> // We want the filenames to be based on the iteration // and padded with zeros using std::setw; using std::setfill; // This works with g77. Different compilers require different // name mangling. '''#define XdmfWrite xdmfwrite_''' // // C/C++ expect NULL terminated strings. Here is a conversion subroutine. char * DemoConvertFortranString( char *FtnName ) { static char Name[80]; char *np; memcpy(Name, FtnName, 79 ); Name[79] = '\0'; np = &Name[78]; while( ( np > Name ) && ( *np <= ' ') ) { np--; } *np = '\0'; return( Name ); } // // C++ will mangle the name based on the argument list. This tells the // compiler not to mangle the name so we can call it from 'C' (but // really Fortran in this case) // extern "C" { // void '''XdmfWrite(''' char *FtnName, int *Iteration, int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points, XdmfInt32 *Conns, XdmfFloat64 *NodeData, XdmfFloat64 *CellData){ char *Name; char FullName[80]; ostrstream DataName(FullName, 80); XdmfDOM dom; XdmfRoot root; XdmfDomain domain; XdmfGrid grid; XdmfTime time; XdmfTopology *topology; XdmfGeometry *geometry; XdmfAttribute nodedata; XdmfAttribute celldata; XdmfArray *array; // Name = DemoConvertFortranString( FtnName ); // root.SetDOM(&dom); root.SetVersion(2.0); root.Build(); // Domain root.Insert(&domain); // Grid grid.SetName("Demonstration Grid"); domain.Insert(&grid); time.SetTimeType(XDMF_TIME_SINGLE); time.SetValue(0.001 * *Iteration); grid.Insert(&time); // Topology topology = grid.GetTopology(); topology->SetTopologyType(XDMF_HEX); topology->SetNumberOfElements(*NumberOfHex); // Fortran is 1 based while c++ is 0 based so // Either subtract 1 from all connections or specify a BaseOffset topology->SetBaseOffset(1); // If you haven't assigned an XdmfArray, GetConnectivity() will create one. array = topology->GetConnectivity(); array->SetNumberOfElements(*NumberOfHex * 8); array->SetValues(0, Conns, *NumberOfHex * 8); // C++ string hocus pocus. // We're actually building the string in FullName[] but were using streams. // the DatasetName will be Demo_00001.h5:/Conns. DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends; // Where the data will actually be written array->SetHeavyDataSetName(FullName); // Geometry geometry = grid.GetGeometry(); geometry->SetGeometryType(XDMF_GEOMETRY_XYZ); geometry->SetNumberOfPoints(*NumberOfPoints); array = geometry->GetPoints(); array->SetValues(0, Points, *NumberOfPoints * 3); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends; array->SetHeavyDataSetName(FullName); // Node Data nodedata.SetName("Node Scalar"); nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = nodedata.GetValues(); array->SetNumberOfElements(*NumberOfPoints); array->SetValues(0, NodeData, *NumberOfPoints); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends; array->SetHeavyDataSetName(FullName); // Cell Data celldata.SetName("Cell Scalar"); celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = celldata.GetValues(); array->SetNumberOfElements(*NumberOfHex); array->SetValues(0, CellData, *NumberOfHex); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends; array->SetHeavyDataSetName(FullName); // Attach and Write grid.Insert(&nodedata); grid.Insert(&celldata); // Build is recursive ... it will be called on all of the child nodes. // This updates the DOM and writes the HDF5 root.Build(); // Write the XML DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends; dom.Write(FullName); } } Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()''' Original : KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Modified : INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) INPNT = IDIM * JDIM * KDIM KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES '''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)''' 1000 CONTINUE CLOSE ( IUNIT ) C END Now the program produces one HDF5 file and one XML file for each iteration. The final step would be to group all of these together so we could animate them over time. Instead of duplicating the XML in another file for each grid, we can use a little XML magic to pull them together : <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0"> <Domain> <Grid GridType="Collection" CollectionType="Temporal"> <xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> </Grid> </Domain> </Xdmf> This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists of the first (in our case, the only) grid in each file. This XML file could be generated programmtically or by a post processing script. a196dc78fada2864eff2feeea49e334784c09df8 50 48 2008-05-02T19:45:47Z Jerry 2 wikitext text/x-wiki == Writing Xdmf from Fortran == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider the following Fortran program which build a grid of Hexahedra with some node and cell centered values : CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Grid of Hexahedron Centered at 0,0,0 C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN ) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) INTEGER I, J, K, IDX REAL*8 X, Y, Z, DX, DY, DZ C Print *, 'Size = ', IDIM, JDIM, KDIM PRINT *, 'Initialze Problem' C XYZ Values of Nodes C From -1 to 1 DX = 2.0 / ( IDIM - 1 ) DY = 2.0 / ( JDIM - 1 ) DZ = 2.0 / ( KDIM - 1 ) Z = -1.0 DO 112 K= 1, KDIM Y = -1.0 DO 111 J= 1, JDIM X = -1.0 DO 110 I= 1, IDIM XYZ( 1, I, J, K ) = X XYZ( 2, I, J, K ) = Y XYZ( 3, I, J, K ) = Z X = X + DX 110 CONTINUE Y = Y + DY 111 CONTINUE Z = Z + DZ 112 CONTINUE C Connections IDX = 1 DO 122 K= 0, KDIM - 2 DO 121 J= 0, JDIM - 2 DO 120 I= 1, IDIM - 1 ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I IDX = IDX + 1 120 CONTINUE 121 CONTINUE 122 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Node Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) INTEGER I, J, K REAL*8 X, Y, Z PRINT *, 'Calculating Node Centered Data' DO 212, K=1, KDIM DO 211, J=1, JDIM DO 210, I=1, IDIM X = XYZ( 1, I, J, K ) Y = XYZ( 2, I, J, K ) Z = XYZ( 3, I, J, K ) NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z )) 210 CONTINUE 211 CONTINUE 212 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Cell Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) INTEGER IDIM, JDIM, KDIM, ITER, KICKER REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) INTEGER I, J, K PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER DO 312, K=1, KDIM - 1 DO 311, J=1, JDIM - 1 DO 310, I=1, IDIM - 1 X = XYZ( 1, I, J, K ) CCVALUES( I, J, K ) = C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) / C EXP( X / ( 1.0 * ITER ) ) 310 CONTINUE 311 CONTINUE 312 CONTINUE C Waste Time DO 313 I=1, 1000000 X = 0.1 * ITER / I Y = SQRT( X * X ) Z = EXP( Y ) 313 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Main Program : C Initialize Grid C Initialize Node Centered Data C For Iteration = 1 to 10 C Generate Cell Centered Data C Done C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC PROGRAM HexMesh PARAMETER ( IDIM = 11 ) PARAMETER ( JDIM = 13 ) PARAMETER ( KDIM = 15 ) REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) C REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) C INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) C INTEGER ITER, KICKER, NITER, NARG INTEGER IUNIT CHARACTER*80 ARGIN C NARG = IARGC() IF( NARG .GE. 1 ) THEN CALL GETARG( 1, ARGIN ) READ( ARGIN, '(I)') NITER ELSE NITER = 10 ENDIF CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN ) CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) C IUNIT = 14 OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) IDIM * JDIM * KDIM WRITE ( IUNIT, * ) XYZ CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) WRITE ( IUNIT, * ) ICONN CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) NCVALUES CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' ) REWIND IUNIT C KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML via print statements (we could also shove bamboo shoots under our fingernails). A better approach would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary Xdmf calls to produce valid Xdmf XML and HDF5 files : #include <Xdmf.h> // We want the filenames to be based on the iteration // and padded with zeros using std::setw; using std::setfill; // This works with g77. Different compilers require different // name mangling. '''#define XdmfWrite xdmfwrite_''' // // C/C++ expect NULL terminated strings. Here is a conversion subroutine. char * DemoConvertFortranString( char *FtnName ) { static char Name[80]; char *np; memcpy(Name, FtnName, 79 ); Name[79] = '\0'; np = &Name[78]; while( ( np > Name ) && ( *np <= ' ') ) { np--; } *np = '\0'; return( Name ); } // // C++ will mangle the name based on the argument list. This tells the // compiler not to mangle the name so we can call it from 'C' (but // really Fortran in this case) // extern "C" { // void '''XdmfWrite(''' char *FtnName, int *Iteration, int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points, XdmfInt32 *Conns, XdmfFloat64 *NodeData, XdmfFloat64 *CellData){ char *Name; char FullName[80]; ostrstream DataName(FullName, 80); XdmfDOM dom; XdmfRoot root; XdmfDomain domain; XdmfGrid grid; XdmfTime time; XdmfTopology *topology; XdmfGeometry *geometry; XdmfAttribute nodedata; XdmfAttribute celldata; XdmfArray *array; // Name = DemoConvertFortranString( FtnName ); // root.SetDOM(&dom); root.SetVersion(2.0); root.Build(); // Domain root.Insert(&domain); // Grid grid.SetName("Demonstration Grid"); domain.Insert(&grid); time.SetTimeType(XDMF_TIME_SINGLE); time.SetValue(0.001 * *Iteration); grid.Insert(&time); // Topology topology = grid.GetTopology(); topology->SetTopologyType(XDMF_HEX); topology->SetNumberOfElements(*NumberOfHex); // Fortran is 1 based while c++ is 0 based so // Either subtract 1 from all connections or specify a BaseOffset topology->SetBaseOffset(1); // If you haven't assigned an XdmfArray, GetConnectivity() will create one. array = topology->GetConnectivity(); array->SetNumberOfElements(*NumberOfHex * 8); array->SetValues(0, Conns, *NumberOfHex * 8); // C++ string hocus pocus. // We're actually building the string in FullName[] but were using streams. // the DatasetName will be Demo_00001.h5:/Conns. DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends; // Where the data will actually be written array->SetHeavyDataSetName(FullName); // Geometry geometry = grid.GetGeometry(); geometry->SetGeometryType(XDMF_GEOMETRY_XYZ); geometry->SetNumberOfPoints(*NumberOfPoints); array = geometry->GetPoints(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetValues(0, Points, *NumberOfPoints * 3); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends; array->SetHeavyDataSetName(FullName); // Node Data nodedata.SetName("Node Scalar"); nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = nodedata.GetValues(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetNumberOfElements(*NumberOfPoints); array->SetValues(0, NodeData, *NumberOfPoints); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends; array->SetHeavyDataSetName(FullName); // Cell Data celldata.SetName("Cell Scalar"); celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = celldata.GetValues(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetNumberOfElements(*NumberOfHex); array->SetValues(0, CellData, *NumberOfHex); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends; array->SetHeavyDataSetName(FullName); // Attach and Write grid.Insert(&nodedata); grid.Insert(&celldata); // Build is recursive ... it will be called on all of the child nodes. // This updates the DOM and writes the HDF5 root.Build(); // Write the XML DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends; dom.Write(FullName); } } Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()''' Original : KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Modified : INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) INPNT = IDIM * JDIM * KDIM KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES '''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)''' 1000 CONTINUE CLOSE ( IUNIT ) C END The program now produces one HDF5 file and one XML file for each iteration. Here is one of the XML output files : <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2"> <Domain> <Grid Name="Demonstration Grid" GridType="Uniform"> <Topology TopologyType="Hexahedron" NumberOfElements="1680 " BaseOffset="1"> <DataItem Dimensions="13440 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Conns</DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Dimensions="6435 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Points</DataItem> </Geometry> <Time TimeType="Single" Value="0.004"/> <Attribute Name="Node Scalar" AttributeType="Scalar" Center="Node"> <DataItem Dimensions="2145 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/NodeData</DataItem> </Attribute> <Attribute Name="Cell Scalar" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="1680 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/CellData</DataItem> </Attribute> </Grid> </Domain> </Xdmf> The final step would be to group all of these together so we could animate them over time. Instead of duplicating the XML in another file for each grid, we can use a little XML magic to pull them together : <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0"> <Domain> <Grid GridType="Collection" CollectionType="Temporal"> <xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> </Grid> </Domain> </Xdmf> This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists of the first (in our case, the only) grid in each file. This XML file could be generated programmtically or by a post processing script. f435025c6637027525f33dd109c1e42ca402c44d Write from Fortran 0 10 51 50 2008-05-08T18:16:23Z Jerry 2 wikitext text/x-wiki == Writing Xdmf from Fortran == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider the following Fortran program which build a grid of Hexahedra with some node and cell centered values : CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Grid of Hexahedron Centered at 0,0,0 C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN ) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) INTEGER I, J, K, IDX REAL*8 X, Y, Z, DX, DY, DZ C Print *, 'Size = ', IDIM, JDIM, KDIM PRINT *, 'Initialze Problem' C XYZ Values of Nodes C From -1 to 1 DX = 2.0 / ( IDIM - 1 ) DY = 2.0 / ( JDIM - 1 ) DZ = 2.0 / ( KDIM - 1 ) Z = -1.0 DO 112 K= 1, KDIM Y = -1.0 DO 111 J= 1, JDIM X = -1.0 DO 110 I= 1, IDIM XYZ( 1, I, J, K ) = X XYZ( 2, I, J, K ) = Y XYZ( 3, I, J, K ) = Z X = X + DX 110 CONTINUE Y = Y + DY 111 CONTINUE Z = Z + DZ 112 CONTINUE C Connections IDX = 1 DO 122 K= 0, KDIM - 2 DO 121 J= 0, JDIM - 2 DO 120 I= 1, IDIM - 1 ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I IDX = IDX + 1 120 CONTINUE 121 CONTINUE 122 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Node Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) INTEGER I, J, K REAL*8 X, Y, Z PRINT *, 'Calculating Node Centered Data' DO 212, K=1, KDIM DO 211, J=1, JDIM DO 210, I=1, IDIM X = XYZ( 1, I, J, K ) Y = XYZ( 2, I, J, K ) Z = XYZ( 3, I, J, K ) NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z )) 210 CONTINUE 211 CONTINUE 212 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Cell Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) INTEGER IDIM, JDIM, KDIM, ITER, KICKER REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) INTEGER I, J, K PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER DO 312, K=1, KDIM - 1 DO 311, J=1, JDIM - 1 DO 310, I=1, IDIM - 1 X = XYZ( 1, I, J, K ) CCVALUES( I, J, K ) = C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) / C EXP( X / ( 1.0 * ITER ) ) 310 CONTINUE 311 CONTINUE 312 CONTINUE C Waste Time DO 313 I=1, 1000000 X = 0.1 * ITER / I Y = SQRT( X * X ) Z = EXP( Y ) 313 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Main Program : C Initialize Grid C Initialize Node Centered Data C For Iteration = 1 to 10 C Generate Cell Centered Data C Done C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC PROGRAM HexMesh PARAMETER ( IDIM = 11 ) PARAMETER ( JDIM = 13 ) PARAMETER ( KDIM = 15 ) REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) C REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) C INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) C INTEGER ITER, KICKER, NITER, NARG INTEGER IUNIT CHARACTER*80 ARGIN C NARG = IARGC() IF( NARG .GE. 1 ) THEN CALL GETARG( 1, ARGIN ) READ( ARGIN, '(I)') NITER ELSE NITER = 10 ENDIF CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN ) CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) C IUNIT = 14 OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) IDIM * JDIM * KDIM WRITE ( IUNIT, * ) XYZ CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) WRITE ( IUNIT, * ) ICONN CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) NCVALUES CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' ) REWIND IUNIT C KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML via print statements (we could also shove bamboo shoots under our fingernails). A better approach would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary Xdmf calls to produce valid Xdmf XML and HDF5 files : #include <Xdmf.h> // We want the filenames to be based on the iteration // and padded with zeros using std::setw; using std::setfill; // This works with g77. Different compilers require different // name mangling. '''#define XdmfWrite xdmfwrite_''' // // C/C++ expect NULL terminated strings. Here is a conversion subroutine. char * DemoConvertFortranString( char *FtnName ) { static char Name[80]; char *np; memcpy(Name, FtnName, 79 ); Name[79] = '\0'; np = &Name[78]; while( ( np > Name ) && ( *np <= ' ') ) { np--; } *np = '\0'; return( Name ); } // // C++ will mangle the name based on the argument list. This tells the // compiler not to mangle the name so we can call it from 'C' (but // really Fortran in this case) // extern "C" { // void '''XdmfWrite(''' char *FtnName, int *Iteration, int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points, XdmfInt32 *Conns, XdmfFloat64 *NodeData, XdmfFloat64 *CellData){ char *Name; char FullName[80]; ostrstream DataName(FullName, 80); XdmfDOM dom; XdmfRoot root; XdmfDomain domain; XdmfGrid grid; XdmfTime time; XdmfTopology *topology; XdmfGeometry *geometry; XdmfAttribute nodedata; XdmfAttribute celldata; XdmfArray *array; Name = DemoConvertFortranString( FtnName ); root.SetDOM(&dom); root.SetVersion(2.0); root.Build(); // Domain root.Insert(&domain); // Grid grid.SetName("Demonstration Grid"); domain.Insert(&grid); time.SetTimeType(XDMF_TIME_SINGLE); time.SetValue(0.001 * *Iteration); grid.Insert(&time); // Topology topology = grid.GetTopology(); topology->SetTopologyType(XDMF_HEX); topology->SetNumberOfElements(*NumberOfHex); // Fortran is 1 based while c++ is 0 based so // Either subtract 1 from all connections or specify a BaseOffset topology->SetBaseOffset(1); // If you haven't assigned an XdmfArray, GetConnectivity() will create one. array = topology->GetConnectivity(); array->SetNumberOfElements(*NumberOfHex * 8); array->SetValues(0, Conns, *NumberOfHex * 8); // C++ string hocus pocus. // We're actually building the string in FullName[] but were using streams. // the DatasetName will be Demo_00001.h5:/Conns. DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends; // Where the data will actually be written array->SetHeavyDataSetName(FullName); // Geometry geometry = grid.GetGeometry(); geometry->SetGeometryType(XDMF_GEOMETRY_XYZ); geometry->SetNumberOfPoints(*NumberOfPoints); array = geometry->GetPoints(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetValues(0, Points, *NumberOfPoints * 3); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends; array->SetHeavyDataSetName(FullName); // Node Data nodedata.SetName("Node Scalar"); nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = nodedata.GetValues(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetNumberOfElements(*NumberOfPoints); array->SetValues(0, NodeData, *NumberOfPoints); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends; array->SetHeavyDataSetName(FullName); // Cell Data celldata.SetName("Cell Scalar"); celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = celldata.GetValues(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetNumberOfElements(*NumberOfHex); array->SetValues(0, CellData, *NumberOfHex); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends; array->SetHeavyDataSetName(FullName); // Attach and Write grid.Insert(&nodedata); grid.Insert(&celldata); // Build is recursive ... it will be called on all of the child nodes. // This updates the DOM and writes the HDF5 root.Build(); // Write the XML DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends; dom.Write(FullName); } } Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()''' Original : KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Modified : INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) INPNT = IDIM * JDIM * KDIM KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES '''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)''' 1000 CONTINUE CLOSE ( IUNIT ) C END The program now produces one HDF5 file and one XML file for each iteration. Here is one of the XML output files : <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2"> <Domain> <Grid Name="Demonstration Grid" GridType="Uniform"> <Topology TopologyType="Hexahedron" NumberOfElements="1680 " BaseOffset="1"> <DataItem Dimensions="13440 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Conns</DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Dimensions="6435 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Points</DataItem> </Geometry> <Time TimeType="Single" Value="0.004"/> <Attribute Name="Node Scalar" AttributeType="Scalar" Center="Node"> <DataItem Dimensions="2145 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/NodeData</DataItem> </Attribute> <Attribute Name="Cell Scalar" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="1680 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/CellData</DataItem> </Attribute> </Grid> </Domain> </Xdmf> The final step would be to group all of these together so we could animate them over time. Instead of duplicating the XML in another file for each grid, we can use a little XML magic to pull them together : <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0"> <Domain> <Grid GridType="Collection" CollectionType="Temporal"> <xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> </Grid> </Domain> </Xdmf> This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists of the first (in our case, the only) grid in each file. This XML file could be generated programmtically or by a post processing script. 9966b8b704f1a5d6a82cb3124e580f8ce14dbe3d Main Page 0 1 52 46 2008-05-23T14:32:39Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 548626a3187be500fa743d5f2058abe039ac9b5f 56 52 2008-08-26T15:41:43Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] '''Mailing list''' xdmf@lists.kitware.com * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 5d72f60ad4aaa8f798397bc01a426ba056ea3da5 62 56 2009-06-26T15:10:03Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Mailing list''' xdmf@lists.kitware.com * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 3fffbeb2d3289cc7ba2f0b8433cb5161dace12a6 67 62 2009-06-26T15:29:07Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Perform Parallel IO with MPI]] '''Mailing list''' xdmf@lists.kitware.com * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 31b833957e22d6929eb20eb5dc7e79f47d204d0e 68 67 2009-06-26T16:15:20Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Mailing list''' xdmf@lists.kitware.com * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 3fffbeb2d3289cc7ba2f0b8433cb5161dace12a6 74 68 2010-01-07T14:29:17Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' # [[Xdmf::New()]] '''Mailing list''' xdmf@lists.kitware.com * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 46709e5871480199dceee1da7b5fd7b47f9c563a 82 74 2011-01-18T13:53:58Z Dave.partyka 10 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' # [[Xdmf::New()]] '''Mailing list''' Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf link here] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 390db7105838b205eee140053aab7c360dc87162 83 82 2011-01-18T13:54:13Z Dave.partyka 10 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' # [[Xdmf::New()]] '''Mailing list''' Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] d68e31b55a531091b799085f62762f34d4115327 84 83 2011-01-18T13:55:37Z Dave.partyka 10 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' # [[Xdmf::New()]] '''Mailing list''' # Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 8afc10d64121971ac2c78f0f6c8e00f72e81236c 87 84 2013-02-25T17:20:17Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' * [[Xdmf::New()]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Wiki Account''' * To edit these pages, send an email to Dave DeMarle with XDMF in the subject that includes your preferred user name and email address in the message body. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] bc9daf7575d4197181fc1a3780921f7fac16e388 88 87 2013-02-25T17:32:00Z Dave.demarle 5 Reverted edits by [[Special:Contributions/Dave.demarle|Dave.demarle]] ([[User_talk:Dave.demarle|Talk]]); changed back to last version by [[User:Dave.partyka|Dave.partyka]] wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' # [[Xdmf::New()]] '''Mailing list''' # Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 8afc10d64121971ac2c78f0f6c8e00f72e81236c 89 88 2013-02-25T17:33:36Z Dave.demarle 5 Undo revision 88 by [[Special:Contributions/Dave.demarle]] ([[User talk:Dave.demarle]]) wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' * [[Xdmf::New()]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Wiki Account''' * To edit these pages, send an email to Dave DeMarle with XDMF in the subject that includes your preferred user name and email address in the message body. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] bc9daf7575d4197181fc1a3780921f7fac16e388 90 89 2013-03-01T08:31:11Z Jk 12 added URL at which to report bugs about XDMF wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' * [[Xdmf::New()]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. '''Wiki Account''' * To edit these pages, send an email to Dave DeMarle with XDMF in the subject that includes your preferred user name and email address in the message body. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 0bd62a687f5bb49584df30e28203b352c1dc319f 96 90 2014-07-25T18:31:53Z Imikejackson 18 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''What's Next''' * [[Xdmf::New()]] '''Version 3 Feature Request''' * [[V3_Road_Feature_Request]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. '''Wiki Account''' * To edit these pages, send an email to Dave DeMarle with XDMF in the subject that includes your preferred user name and email address in the message body. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] c209749a55f7c96ccf86f840f6bb94108cd432bb 97 96 2014-08-19T18:14:08Z Dave.demarle 5 start updating to xdmf3 and adding more useful content wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Examples''' * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Xdmf::New()|'''What's Next''']] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. '''Wiki Account''' * To edit these pages, send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 53a5f4a30a029682e1888fdbf093c08f7c30d54e 99 97 2014-08-19T18:37:31Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Xdmf::New()|'''What's Next''']] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === web site administration === '''Wiki Account''' * To edit these pages, send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 5806c3bbcdde6c477b08195ee0254ff345c00f86 Read from MySQL 0 11 53 2008-05-23T14:37:21Z Jerry 2 New page: == '''Accessing a MySQL DataBase''' == Partial support for reading data from a MySQL database is available. MySQL is treated as another HeavyData format like HDF5. Currently database acce... wikitext text/x-wiki == '''Accessing a MySQL DataBase''' == Partial support for reading data from a MySQL database is available. MySQL is treated as another HeavyData format like HDF5. Currently database access is ReadOnly and is accessed by setting the '''Format''' of the '''DataItem''' in XML equal to '''MySQL''' <Attribute Name="Cell Centered Values" Center="Cell"> <DataItem Format="MySQL" Server="localhost" User="root" DataBase="MnmiFromout" Dimensions="3" NumberType="Float"> <![CDATA[SELECT X FROM Locations WHERE Time < 0.21]]> </DataItem> </Attribute> ef062d9c828e7034750dc454e9ba71a82080e911 54 53 2008-05-23T14:44:03Z Jerry 2 wikitext text/x-wiki == '''Accessing a MySQL DataBase''' == Partial support for reading data from a MySQL database is available. MySQL is treated as another HeavyData format like HDF5. Currently database access is ReadOnly and is accessed by setting the '''Format''' of the '''DataItem''' in XML equal to '''MySQL''' <Attribute Name="Cell Centered Values" Center="Cell"> <DataItem Format="MySQL" Server="localhost" User="root" DataBase="MnmiFromout" Dimensions="3" NumberType="Float"> <![CDATA[SELECT X FROM Locations WHERE Time < 0.21]]> </DataItem> </Attribute> A Valid SQL statement is placed in the CDATA of the DataItem. When the XdmfDataItem is updated, an atomic query is made and the result is placed in the XdmfArray of the DataItem. Putting a "<" (less than) in the CDATA will cause an error in the XML parser. The XML example above shows how to do this correctly. The Server, User, and DataBase attributes tell Xdmf how to access MySQL. There is also a Password attribute. Currently this is just clear text which is a really bad idea. This will change. 0a92c614bc7e98a07ec0e028155cb19a2035ca4e XDMF API 0 3 55 44 2008-07-24T23:35:23Z Berk 4 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parse strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement ( XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1 ) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfTime''' When UpdateInformation() gets called for a Grid, an XdmfTime object is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there is a &lt;Time&gt; element in the Grid the object is populated. If the Grid is Non-Uniform (i.e. Collection, Tree), the children are updated as well. If the parent is TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the appropriate value set. Methods : XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0) This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten. XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax) this checks to see if the Time is entirely in Min/Max. Since this is a float comparison, I added an Epsilon member to XdmfTime with default value = 1e-7. This may be changed via XdmfTime::SetEpsilon() XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill) This populates the array with the direct children that are entirely in min/max. For example if the range is 0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL. '''XdmfHDF''' In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) # If an array is given a HeavyDataSetName, that is # where it will be written p.setHeavyDataSetName('MyData.h5:/Pressure') g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file ba1233a3c254f628c8e2262a0c99372e321105bc XDMF Model and Format 0 2 57 45 2008-09-30T16:03:26Z Jerry 2 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 339024a9c3c48ee1e9b0f1f7c466b384689dd34b 73 57 2009-09-16T17:51:20Z Dave.demarle 5 update to mention globalid attribute wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") f20f7c57ce83963ffe8cba1bc9ab9bc3ea67f449 85 73 2011-10-28T19:14:11Z Dave.demarle 5 document binary heavy data format wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian Native | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek bytes (applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") f1753c889a858f8414faeae5388dce5915f90272 86 85 2011-10-28T19:17:29Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML(which is a basic substitution mechanism), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 936ea1357ce3ee16dc295b2fa1b9ad3fcc5cc4eb 91 86 2013-03-01T09:11:51Z Jk 12 added small section and example regarding XML entities. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 05d341521ee6e3e137c45f99954b60b56f3c9971 92 91 2013-03-01T09:17:39Z Jk 12 added reference to Origin_DxDy where Origin_DxDyDz is mentioned wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Or ''' ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") dd17931d0bfc897d775af0af7134005870224140 93 92 2013-04-03T11:49:48Z Jk 12 two minor corrections on code blocks (one split and two joined) wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | <span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 68d0cc630b1532f6b733bf4c46dc4fb2b5231707 94 93 2014-07-25T17:45:35Z Imikejackson 18 Adding update for 16 bit integer writing wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") dbfc6f7c2523db7dc46fae5158a538785450a26e Write Xdmf 0 9 58 49 2009-01-23T13:30:02Z Jerry 2 wikitext text/x-wiki == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetShapeFromString("10 20 30") p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> ~ c352d0c23ffc049c89f649508391b44b3d580f0b 59 58 2009-01-23T20:41:30Z Jerry 2 wikitext text/x-wiki == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetShapeFromString("10 20 30") p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is built, the XML is blindly copied in and the writing of HeavyData is skipped. #!/usr/bin/env python from Xdmf import * # Example of How to Generate Xdmf # The Heavy Data for the Attribute is written separately # Write H5 Data arr = XdmfArray() arr.SetNumberType(XDMF_FLOAT64_TYPE) arr.SetShapeFromString("10 20 30") arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1) h5 = XdmfHDF() h5.CopyType(arr) h5.CopyShape(arr) h5.Open('XdmfByHand.h5:/Mydata', 'w') h5.Write(arr) h5.Close() DataXml = """<DataItem Dimensions="10 20 30" NumberType="Float" Precision="8" Format="HDF"> XdmfByHand.h5:/Mydata </DataItem>""" # d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); # Insert the raw XML attr.SetDataXml(DataXml) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file This results in identical XML with just the name of the HDF5 dataset changed. ~ 76e395d21b1a554317289c4d5d45505f148c2fbe 60 59 2009-01-23T20:42:11Z Jerry 2 wikitext text/x-wiki == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetShapeFromString("10 20 30") p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is built, the XML is blindly copied in and the writing of HeavyData is skipped. #!/usr/bin/env python from Xdmf import * # Example of How to Generate Xdmf # The Heavy Data for the Attribute is written separately # Write H5 Data arr = XdmfArray() arr.SetNumberType(XDMF_FLOAT64_TYPE) arr.SetShapeFromString("10 20 30") arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1) h5 = XdmfHDF() h5.CopyType(arr) h5.CopyShape(arr) h5.Open('XdmfByHand.h5:/Mydata', 'w') h5.Write(arr) h5.Close() DataXml = """<DataItem Dimensions="10 20 30" NumberType="Float" Precision="8" Format="HDF"> XdmfByHand.h5:/Mydata </DataItem>""" # d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); # Insert the raw XML attr.SetDataXml(DataXml) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file This results in identical XML with just the name of the HDF5 dataset changed. ~ 1d0aa9675411d278bebd5899d817b2cf84652e92 61 60 2009-01-26T21:22:19Z Jerry 2 wikitext text/x-wiki == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetShapeFromString("10 20 30") p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is built, the XML is blindly copied in and the writing of HeavyData is skipped. #!/usr/bin/env python from Xdmf import * # Example of How to Generate Xdmf # The Heavy Data for the Attribute is written separately # Write H5 Data arr = XdmfArray() arr.SetNumberType(XDMF_FLOAT64_TYPE) arr.SetShapeFromString("10 20 30") arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1) h5 = XdmfHDF() h5.CopyType(arr) h5.CopyShape(arr) h5.Open('XdmfByHand.h5:/Mydata', 'w') h5.Write(arr) h5.Close() # Use XdmfValuesHDF to generate the appropriate # Xdmf XML from and existing HDF5 dataset dv = XdmfValuesHDF() DataXml = dv.DataItemFromHDF('XdmfByHand.h5:/Mydata') # # Now build the tree of objects d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); # Insert the raw XML attr.SetDataXml(DataXml) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file This results in identical XML with just the name of the HDF5 dataset changed. ~ ba7310e7f381f341364c895900649b81600b5192 Parallel IO with MPI 0 12 63 2009-06-26T15:12:30Z Jerry 2 New page: (code and description provided by Will Dicharry) === Controlling the I/O process for XdmfHeavyData === The XDMF API provides a customization point to allow the heavy data sets to be writ... wikitext text/x-wiki (code and description provided by Will Dicharry) === Controlling the I/O process for XdmfHeavyData === The XDMF API provides a customization point to allow the heavy data sets to be written in a certain manner, depending on the application environment and independent of the heavy dataset format. New I/O strategies can be implemented by subclassing the callback classes defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes. This method has the advantage of applying a common strategy to any XdmfHeavyData subclass. The system works in the following way: XdmfHeavyData contains the non-virtual methods Open, Close, Read, and Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite. XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment. In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely. === Example === Suppose we have an MPI environment with 4 processes. Each process contains part of an array with 100 values numbered 0 to 99; process 0 with items 0-24, process 1 with items 25-49, etc. We would like to write this data to a single HDF file containing a single array of 100 values, stored in increasing numerical order. To do this, we will communicate all of the data to process 0 and let process 0 handle the actual output of the array. We start by including the necessary headers and defining a very simple stream buffer utility class that simplifies encoding and decoding data between processes: <code> #include <mpi.h> #include <XdmfArray.h> #include <XdmfHDF.h> /// Simple memory buffer implementation that keeps track of it's stream pointer. class Buffer { private: std::size_t m_size; char* m_data; char* m_put; char* m_tell; public: Buffer( std::size_t size ) : m_size( size ), m_data( new char[size] ), m_put( m_data ), m_tell( m_data ) {} ~Buffer() { delete [] m_data; } /// copy a contiguous block into the buffer void put( const void* data, std::size_t size ) { memcpy( m_put, data, size ); m_put += size; } /// put a single value into the buffer template< typename T > void put( const T& t ) { std::size_t size = sizeof( T ); put( &t, size ); } /// copy a contiguous block of data from the buffer to an already /// allocated location void tell( void* out, std::size_t size ) { memcpy( out, m_tell, size ); m_tell += size; } /// Copy a single value into the buffer. template< typename T > T tell() { std::size_t tsize = sizeof( T ); T tmp; tell( &tmp, tsize ); return tmp; } std::size_t size() const { return m_size; } char* pointer() { return m_data; } void reset() { m_put = m_data; m_tell = m_data; } }; </code> We haven't yet called on the Xdmf API to do anything, the Buffer class is just a utility that we will use later. Now, we write our callback class that will customize the process of opening, reading, writing, and closing the heavy dataset. Since our communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback, XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes has a single virtual method that takes a pointer to a XdmfHeavyData and the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close, XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods. <code> /// Callback implements parallel IO by communicating to process 0 class CommunicationCallback : public XdmfOpenCallback, public XdmfWriteCallback, public XdmfCloseCallback, public XdmfReadCallback { private: int mCommRank; int mCommSize; public: /// Constructor initializes the Number of processors and local process /// ID. CommunicationCallback() { MPI_Comm_size( MPI_COMM_WORLD, &mCommSize ); MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank ); } /// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going /// to read or write, so only rank 0 will open the file. XdmfInt32 DoOpen( XdmfHeavyData* ds, XdmfConstString name, XdmfConstString access ) { if ( mCommRank == 0 ) { // Call the actual DoOpen method from XdmfHeavyData return ds->DoOpen( name, access ); } else { // Not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0 /// needs to do anything. XdmfInt32 DoClose( XdmfHeavyData* ds ) { if ( mCommRank == 0 ) { // Call the heavy dataset's native close method. return ds->DoClose(); } else { // not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfWriteCallback::DoWrite. If the local /// process ID is 0, then we expect to receive data from everyone /// else. Otherwise, we send data. Rank 0 does all of the writing. XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array ) { // This implementation assumes process 0 has the same data // size as everyone else // set up a stream buffer that is large enough to hold the data to // be sent or received. We require enough space for the rank, // start, stride, and count for the array plus enough space to hold // the actual array data. XdmfInt64 start[1], stride[1], count[1]; XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count ); std::size_t slab_info_size = sizeof( XdmfInt32 ) // slab rank + slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count Buffer buf( slab_info_size + array->GetCoreLength() ); // If the local process ID is nonzero, pack the buffer and send to // process 0. if ( mCommRank != 0 ) { // copy rank and slab information into the buffer. buf.put( slab_rank ); for ( int i = 0; i < slab_rank; ++i ) { buf.put( start[i] ); buf.put( stride[i] ); buf.put( count[i] ); } // copy the actual data into the buffer. buf.put( array->GetDataPointer(), array->GetCoreLength() ); // send to rank 0 in the global communicator. MPI_Send( buf.pointer(), buf.size(), MPI_BYTE, 0, 0, MPI_COMM_WORLD ); } else { // Local process ID is 0, so we write local data then receive and // write remote data. // first, it's easy to write the local data ds->DoWrite( array ); int processes_received = 1; // local data for process 0 is written // loop until the data for all processes has been received. while ( processes_received < mCommSize ) { // Fill the buffer with incoming data. We are assuming here // that all processes contain the same amount of data. MPI_Recv( buf.pointer(), buf.size(), MPI_BYTE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, 0 ); processes_received++; // unpack the buffer buf.reset(); // reset the stream pointer to the beginning // we mean rank in the linear algebra sense here slab_rank = buf.tell< XdmfInt32 >(); // start, stride, and count are next. for( int i = 0; i < slab_rank; ++i ) { start[i] = buf.tell< XdmfInt64 >(); stride[i] = buf.tell< XdmfInt64 >(); count[i] = buf.tell< XdmfInt64 >(); } // select the correct hyper slab in the heavy data set. ds->SelectHyperSlab( start, stride, count ); // allocate an array to hold the off-core data. XdmfArray* recv = new XdmfArray; recv->CopyShape( array ); // place the received data into the array. buf.tell( recv->GetDataPointer(), recv->GetCoreLength() ); // write the off core data to the dataset by calling the heavy // data's DoWrite method. ds->DoWrite( recv ); delete recv; } } return XDMF_SUCCESS; } /// Reimplemented from XdmfReadCallback::DoRead. Read the data from a /// heavy data source into an array only if the local process ID is 0. /// Otherwise, do nothing. XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array ) { if ( mCommRank == 0 ) { // defer to the actual heavy data implementation of DoRead. return ds->DoRead( array ); } else { // return an empty array. return NULL; } } }; // end of class CommunicationCallback </code> One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well. Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip. <code> char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI"; int main( int argc, char* argv[] ) { // Initialize MPI MPI_Init( &argc, &argv ); // determine the local process ID int rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // Create an HDF dataset to write out to. XdmfHDF* H5 = new XdmfHDF(); // Attach an instance of the CommunicationCallback class defined above // to customize opening, writing, and closing the dataset. CommunicationCallback* cb = new CommunicationCallback; H5->setOpenCallback( cb ); H5->setWriteCallback( cb ); H5->setCloseCallback(cb ); // Allocate an array of size 25 and fill it with values depending // on the local process ID (process 0 has 0-24, process 1 has // 25-49,...) XdmfArray* MyData = new XdmfArray(); MyData->SetNumberType( XDMF_FLOAT32_TYPE ); MyData->SetNumberOfElements( 25 ); MyData->Generate( rank * 25, rank*25 + 24 ); // Set the dataset's type to the array's type H5->CopyType( MyData ); // Set up the dimensions of the dataset. XdmfInt64 dims[1]; dims[0] = 100; H5->SetShape( 1, dims ); // Set up the hyper slab for the dataset. Each process will select a // distinct portion of the dataset (process 0 has 0-24, process 1 // 25-49,...) XdmfInt64 start[1], stride[1], count[1]; start[0] = rank * 25; stride[0] = 1; count[0] = 25; // select the slab in the dataset corresponding to the local process. H5->SelectHyperSlab( start, stride, count ); // Open the dataset. H5->Open( kDatasetName, "w" ); // Write the array. H5->Write( MyData ); // Close the dataset. H5->Close(); // writing is complete, now we have a quick test to ensure the data // survives a round trip. bool failure = false; // Create a new dataset to read from XdmfHDF* H5In = new XdmfHDF(); // Use the same callback. H5In->setReadCallback( cb ); H5In->setOpenCallback( cb ); H5In->setCloseCallback( cb ); // Open the dataset for reading. H5In->Open( kDatasetName, "r" ); // Read the data into an array. XdmfArray* result = H5In->Read(); // if the read was successful, make sure the values for all processes // are in the file. if ( result ) { for ( size_t i = 0; i < 100; ++i ) { float value = result->GetValueAsFloat32( i ); std::cout << i << " " << value << std::endl; failure = ( value != i ); } } MPI_Finalize(); delete H5; delete cb; delete MyData; delete H5In; delete result; if ( failure ) { return -1; } else { return 0; } }; </code> Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree. 4a4160c219990d594aaff0ecb081a4ea2c6ce30c 64 63 2009-06-26T15:15:14Z Jerry 2 wikitext text/x-wiki (code and description provided by Will Dicharry) === Controlling the I/O process for XdmfHeavyData === The XDMF API provides a customization point to allow the heavy data sets to be written in a certain manner, depending on the application environment and independent of the heavy dataset format. New I/O strategies can be implemented by subclassing the callback classes defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes. This method has the advantage of applying a common strategy to any XdmfHeavyData subclass. The system works in the following way: XdmfHeavyData contains the non-virtual methods Open, Close, Read, and Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite. XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment. In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely. === Example === Suppose we have an MPI environment with 4 processes. Each process contains part of an array with 100 values numbered 0 to 99; process 0 with items 0-24, process 1 with items 25-49, etc. We would like to write this data to a single HDF file containing a single array of 100 values, stored in increasing numerical order. To do this, we will communicate all of the data to process 0 and let process 0 handle the actual output of the array. We start by including the necessary headers and defining a very simple stream buffer utility class that simplifies encoding and decoding data between processes: <code> #include <mpi.h> #include <XdmfArray.h> #include <XdmfHDF.h> /// Simple memory buffer implementation that keeps track of it's stream pointer. class Buffer { private: std::size_t m_size; char* m_data; char* m_put; char* m_tell; public: Buffer( std::size_t size ) : m_size( size ), m_data( new char[size] ), m_put( m_data ), m_tell( m_data ) {} ~Buffer() { delete [] m_data; } /// copy a contiguous block into the buffer void put( const void* data, std::size_t size ) { memcpy( m_put, data, size ); m_put += size; } /// put a single value into the buffer template< typename T > void put( const T& t ) { std::size_t size = sizeof( T ); put( &t, size ); } /// copy a contiguous block of data from the buffer to an already /// allocated location void tell( void* out, std::size_t size ) { memcpy( out, m_tell, size ); m_tell += size; } /// Copy a single value into the buffer. template< typename T > T tell() { std::size_t tsize = sizeof( T ); T tmp; tell( &tmp, tsize ); return tmp; } std::size_t size() const { return m_size; } char* pointer() { return m_data; } void reset() { m_put = m_data; m_tell = m_data; } }; </code> We haven't yet called on the Xdmf API to do anything, the Buffer class is just a utility that we will use later. Now, we write our callback class that will customize the process of opening, reading, writing, and closing the heavy dataset. Since our communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback, XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes has a single virtual method that takes a pointer to a XdmfHeavyData and the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close, XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods. <code> /// Callback implements parallel IO by communicating to process 0 class CommunicationCallback : public XdmfOpenCallback, public XdmfWriteCallback, public XdmfCloseCallback, public XdmfReadCallback { private: int mCommRank; int mCommSize; public: /// Constructor initializes the Number of processors and local process /// ID. CommunicationCallback() { MPI_Comm_size( MPI_COMM_WORLD, &mCommSize ); MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank ); } /// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going /// to read or write, so only rank 0 will open the file. XdmfInt32 DoOpen( XdmfHeavyData* ds, XdmfConstString name, XdmfConstString access ) { if ( mCommRank == 0 ) { // Call the actual DoOpen method from XdmfHeavyData return ds->DoOpen( name, access ); } else { // Not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0 /// needs to do anything. XdmfInt32 DoClose( XdmfHeavyData* ds ) { if ( mCommRank == 0 ) { // Call the heavy dataset's native close method. return ds->DoClose(); } else { // not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfWriteCallback::DoWrite. If the local /// process ID is 0, then we expect to receive data from everyone /// else. Otherwise, we send data. Rank 0 does all of the writing. XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array ) { // This implementation assumes process 0 has the same data // size as everyone else // set up a stream buffer that is large enough to hold the data to // be sent or received. We require enough space for the rank, // start, stride, and count for the array plus enough space to hold // the actual array data. XdmfInt64 start[1], stride[1], count[1]; XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count ); std::size_t slab_info_size = sizeof( XdmfInt32 ) // slab rank + slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count Buffer buf( slab_info_size + array->GetCoreLength() ); // If the local process ID is nonzero, pack the buffer and send to // process 0. if ( mCommRank != 0 ) { // copy rank and slab information into the buffer. buf.put( slab_rank ); for ( int i = 0; i < slab_rank; ++i ) { buf.put( start[i] ); buf.put( stride[i] ); buf.put( count[i] ); } // copy the actual data into the buffer. buf.put( array->GetDataPointer(), array->GetCoreLength() ); // send to rank 0 in the global communicator. MPI_Send( buf.pointer(), buf.size(), MPI_BYTE, 0, 0, MPI_COMM_WORLD ); } else { // Local process ID is 0, so we write local data then receive and // write remote data. // first, it's easy to write the local data ds->DoWrite( array ); int processes_received = 1; // local data for process 0 is written // loop until the data for all processes has been received. while ( processes_received < mCommSize ) { // Fill the buffer with incoming data. We are assuming here // that all processes contain the same amount of data. MPI_Recv( buf.pointer(), buf.size(), MPI_BYTE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, 0 ); processes_received++; // unpack the buffer buf.reset(); // reset the stream pointer to the beginning // we mean rank in the linear algebra sense here slab_rank = buf.tell< XdmfInt32 >(); // start, stride, and count are next. for( int i = 0; i < slab_rank; ++i ) { start[i] = buf.tell< XdmfInt64 >(); stride[i] = buf.tell< XdmfInt64 >(); count[i] = buf.tell< XdmfInt64 >(); } // select the correct hyper slab in the heavy data set. ds->SelectHyperSlab( start, stride, count ); // allocate an array to hold the off-core data. XdmfArray* recv = new XdmfArray; recv->CopyShape( array ); // place the received data into the array. buf.tell( recv->GetDataPointer(), recv->GetCoreLength() ); // write the off core data to the dataset by calling the heavy // data's DoWrite method. ds->DoWrite( recv ); delete recv; } } return XDMF_SUCCESS; } /// Reimplemented from XdmfReadCallback::DoRead. Read the data from a /// heavy data source into an array only if the local process ID is 0. /// Otherwise, do nothing. XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array ) { if ( mCommRank == 0 ) { // defer to the actual heavy data implementation of DoRead. return ds->DoRead( array ); } else { // return an empty array. return NULL; } } }; // end of class CommunicationCallback </code> One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well. Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip. <code> char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI"; int main( int argc, char* argv[] ) { // Initialize MPI MPI_Init( &argc, &argv ); // determine the local process ID int rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // Create an HDF dataset to write out to. XdmfHDF* H5 = new XdmfHDF(); // Attach an instance of the CommunicationCallback class defined above // to customize opening, writing, and closing the dataset. CommunicationCallback* cb = new CommunicationCallback; H5->setOpenCallback( cb ); H5->setWriteCallback( cb ); H5->setCloseCallback(cb ); // Allocate an array of size 25 and fill it with values depending // on the local process ID (process 0 has 0-24, process 1 has // 25-49,...) XdmfArray* MyData = new XdmfArray(); MyData->SetNumberType( XDMF_FLOAT32_TYPE ); MyData->SetNumberOfElements( 25 ); MyData->Generate( rank * 25, rank*25 + 24 ); // Set the dataset's type to the array's type H5->CopyType( MyData ); // Set up the dimensions of the dataset. XdmfInt64 dims[1]; dims[0] = 100; H5->SetShape( 1, dims ); // Set up the hyper slab for the dataset. Each process will select a // distinct portion of the dataset (process 0 has 0-24, process 1 // 25-49,...) XdmfInt64 start[1], stride[1], count[1]; start[0] = rank * 25; stride[0] = 1; count[0] = 25; // select the slab in the dataset corresponding to the local process. H5->SelectHyperSlab( start, stride, count ); // Open the dataset. H5->Open( kDatasetName, "w" ); // Write the array. H5->Write( MyData ); // Close the dataset. H5->Close(); // writing is complete, now we have a quick test to ensure the data // survives a round trip. bool failure = false; // Create a new dataset to read from XdmfHDF* H5In = new XdmfHDF(); // Use the same callback. H5In->setReadCallback( cb ); H5In->setOpenCallback( cb ); H5In->setCloseCallback( cb ); // Open the dataset for reading. H5In->Open( kDatasetName, "r" ); // Read the data into an array. XdmfArray* result = H5In->Read(); // if the read was successful, make sure the values for all processes // are in the file. if ( result ) { for ( size_t i = 0; i < 100; ++i ) { float value = result->GetValueAsFloat32( i ); std::cout << i << " " << value << std::endl; failure = ( value != i ); } } MPI_Finalize(); delete H5; delete cb; delete MyData; delete H5In; delete result; if ( failure ) { return -1; } else { return 0; } }; </code> Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree. 6fa0c1c2a5b45003677b5c63de891cdcd6a7ea95 65 64 2009-06-26T15:17:04Z Jerry 2 wikitext text/x-wiki (code and description provided by Will Dicharry) === Controlling the I/O process for XdmfHeavyData === The XDMF API provides a customization point to allow the heavy data sets to be written in a certain manner, depending on the application environment and independent of the heavy dataset format. New I/O strategies can be implemented by subclassing the callback classes defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes. This method has the advantage of applying a common strategy to any XdmfHeavyData subclass. The system works in the following way: XdmfHeavyData contains the non-virtual methods Open, Close, Read, and Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite. XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment. In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely. === Example === Suppose we have an MPI environment with 4 processes. Each process contains part of an array with 100 values numbered 0 to 99; process 0 with items 0-24, process 1 with items 25-49, etc. We would like to write this data to a single HDF file containing a single array of 100 values, stored in increasing numerical order. To do this, we will communicate all of the data to process 0 and let process 0 handle the actual output of the array. We start by including the necessary headers and defining a very simple stream buffer utility class that simplifies encoding and decoding data between processes: <code> #include <mpi.h> #include <XdmfArray.h> #include <XdmfHDF.h> /// Simple memory buffer implementation that keeps track of it's stream pointer. class Buffer { private: std::size_t m_size; char* m_data; char* m_put; char* m_tell; public: Buffer( std::size_t size ) : m_size( size ), m_data( new char[size] ), m_put( m_data ), m_tell( m_data ) {} ~Buffer() { delete [] m_data; } /// copy a contiguous block into the buffer void put( const void* data, std::size_t size ) { memcpy( m_put, data, size ); m_put += size; } /// put a single value into the buffer template< typename T > void put( const T& t ) { std::size_t size = sizeof( T ); put( &t, size ); } /// copy a contiguous block of data from the buffer to an already /// allocated location void tell( void* out, std::size_t size ) { memcpy( out, m_tell, size ); m_tell += size; } /// Copy a single value into the buffer. template< typename T > T tell() { std::size_t tsize = sizeof( T ); T tmp; tell( &tmp, tsize ); return tmp; } std::size_t size() const { return m_size; } char* pointer() { return m_data; } void reset() { m_put = m_data; m_tell = m_data; } }; </code> We haven't yet called on the Xdmf API to do anything, the Buffer class is just a utility that we will use later. Now, we write our callback class that will customize the process of opening, reading, writing, and closing the heavy dataset. Since our communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback, XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes has a single virtual method that takes a pointer to a XdmfHeavyData and the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close, XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods. <code> /// Callback implements parallel IO by communicating to process 0 class CommunicationCallback : public XdmfOpenCallback, public XdmfWriteCallback, public XdmfCloseCallback, public XdmfReadCallback { private: int mCommRank; int mCommSize; public: /// Constructor initializes the Number of processors and local process /// ID. CommunicationCallback() { MPI_Comm_size( MPI_COMM_WORLD, &mCommSize ); MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank ); } /// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going /// to read or write, so only rank 0 will open the file. XdmfInt32 DoOpen( XdmfHeavyData* ds, XdmfConstString name, XdmfConstString access ) { if ( mCommRank == 0 ) { // Call the actual DoOpen method from XdmfHeavyData return ds->DoOpen( name, access ); } else { // Not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0 /// needs to do anything. XdmfInt32 DoClose( XdmfHeavyData* ds ) { if ( mCommRank == 0 ) { // Call the heavy dataset's native close method. return ds->DoClose(); } else { // not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfWriteCallback::DoWrite. If the local /// process ID is 0, then we expect to receive data from everyone /// else. Otherwise, we send data. Rank 0 does all of the writing. XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array ) { // This implementation assumes process 0 has the same data // size as everyone else // set up a stream buffer that is large enough to hold the data to // be sent or received. We require enough space for the rank, // start, stride, and count for the array plus enough space to hold // the actual array data. XdmfInt64 start[1], stride[1], count[1]; XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count ); std::size_t slab_info_size = sizeof( XdmfInt32 ) // slab rank + slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count Buffer buf( slab_info_size + array->GetCoreLength() ); // If the local process ID is nonzero, pack the buffer and send to // process 0. if ( mCommRank != 0 ) { // copy rank and slab information into the buffer. buf.put( slab_rank ); for ( int i = 0; i < slab_rank; ++i ) { buf.put( start[i] ); buf.put( stride[i] ); buf.put( count[i] ); } // copy the actual data into the buffer. buf.put( array->GetDataPointer(), array->GetCoreLength() ); // send to rank 0 in the global communicator. MPI_Send( buf.pointer(), buf.size(), MPI_BYTE, 0, 0, MPI_COMM_WORLD ); } else { // Local process ID is 0, so we write local data then receive and // write remote data. // first, it's easy to write the local data ds->DoWrite( array ); int processes_received = 1; // local data for process 0 is written // loop until the data for all processes has been received. while ( processes_received < mCommSize ) { // Fill the buffer with incoming data. We are assuming here // that all processes contain the same amount of data. MPI_Recv( buf.pointer(), buf.size(), MPI_BYTE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, 0 ); processes_received++; // unpack the buffer buf.reset(); // reset the stream pointer to the beginning // we mean rank in the linear algebra sense here slab_rank = buf.tell< XdmfInt32 >(); // start, stride, and count are next. for( int i = 0; i < slab_rank; ++i ) { start[i] = buf.tell< XdmfInt64 >(); stride[i] = buf.tell< XdmfInt64 >(); count[i] = buf.tell< XdmfInt64 >(); } // select the correct hyper slab in the heavy data set. ds->SelectHyperSlab( start, stride, count ); // allocate an array to hold the off-core data. XdmfArray* recv = new XdmfArray; recv->CopyShape( array ); // place the received data into the array. buf.tell( recv->GetDataPointer(), recv->GetCoreLength() ); // write the off core data to the dataset by calling the heavy // data's DoWrite method. ds->DoWrite( recv ); delete recv; } } return XDMF_SUCCESS; } /// Reimplemented from XdmfReadCallback::DoRead. Read the data from a /// heavy data source into an array only if the local process ID is 0. /// Otherwise, do nothing. XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array ) { if ( mCommRank == 0 ) { // defer to the actual heavy data implementation of DoRead. return ds->DoRead( array ); } else { // return an empty array. return NULL; } } }; // end of class CommunicationCallback </code> One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well. Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip. <code> char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI"; int main( int argc, char* argv[] ) { // Initialize MPI MPI_Init( &argc, &argv ); // determine the local process ID int rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // Create an HDF dataset to write out to. XdmfHDF* H5 = new XdmfHDF(); // Attach an instance of the CommunicationCallback class defined above // to customize opening, writing, and closing the dataset. CommunicationCallback* cb = new CommunicationCallback; H5->setOpenCallback( cb ); H5->setWriteCallback( cb ); H5->setCloseCallback(cb ); // Allocate an array of size 25 and fill it with values depending // on the local process ID (process 0 has 0-24, process 1 has // 25-49,...) XdmfArray* MyData = new XdmfArray(); MyData->SetNumberType( XDMF_FLOAT32_TYPE ); MyData->SetNumberOfElements( 25 ); MyData->Generate( rank * 25, rank*25 + 24 ); // Set the dataset's type to the array's type H5->CopyType( MyData ); // Set up the dimensions of the dataset. XdmfInt64 dims[1]; dims[0] = 100; H5->SetShape( 1, dims ); // Set up the hyper slab for the dataset. Each process will select a // distinct portion of the dataset (process 0 has 0-24, process 1 // 25-49,...) XdmfInt64 start[1], stride[1], count[1]; start[0] = rank * 25; stride[0] = 1; count[0] = 25; // select the slab in the dataset corresponding to the local process. H5->SelectHyperSlab( start, stride, count ); // Open the dataset. H5->Open( kDatasetName, "w" ); // Write the array. H5->Write( MyData ); // Close the dataset. H5->Close(); // writing is complete, now we have a quick test to ensure the data // survives a round trip. bool failure = false; // Create a new dataset to read from XdmfHDF* H5In = new XdmfHDF(); // Use the same callback. H5In->setReadCallback( cb ); H5In->setOpenCallback( cb ); H5In->setCloseCallback( cb ); // Open the dataset for reading. H5In->Open( kDatasetName, "r" ); // Read the data into an array. XdmfArray* result = H5In->Read(); // if the read was successful, make sure the values for all processes // are in the file. if ( result ) { for ( size_t i = 0; i < 100; ++i ) { float value = result->GetValueAsFloat32( i ); std::cout << i << " " << value << std::endl; failure = ( value != i ); } } MPI_Finalize(); delete H5; delete cb; delete MyData; delete H5In; delete result; if ( failure ) { return -1; } else { return 0; } }; </code> Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree. 40e09c3994cb23ffd3f8b0eee01a1e7cb04bad9f 66 65 2009-06-26T15:19:01Z Jerry 2 wikitext text/x-wiki (code and description provided by Will Dicharry) === Controlling the I/O process for XdmfHeavyData === The XDMF API provides a customization point to allow the heavy data sets to be written in a certain manner, depending on the application environment and independent of the heavy dataset format. New I/O strategies can be implemented by subclassing the callback classes defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes. This method has the advantage of applying a common strategy to any XdmfHeavyData subclass. The system works in the following way: XdmfHeavyData contains the non-virtual methods Open, Close, Read, and Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite. XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment. In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely. === Example === Suppose we have an MPI environment with 4 processes. Each process contains part of an array with 100 values numbered 0 to 99; process 0 with items 0-24, process 1 with items 25-49, etc. We would like to write this data to a single HDF file containing a single array of 100 values, stored in increasing numerical order. To do this, we will communicate all of the data to process 0 and let process 0 handle the actual output of the array. We start by including the necessary headers and defining a very simple stream buffer utility class that simplifies encoding and decoding data between processes: <code> #include <mpi.h> #include <XdmfArray.h> #include <XdmfHDF.h> /// Simple memory buffer implementation that keeps track of it's stream pointer. class Buffer { private: std::size_t m_size; char* m_data; char* m_put; char* m_tell; public: Buffer( std::size_t size ) : m_size( size ), m_data( new char[size] ), m_put( m_data ), m_tell( m_data ) {} ~Buffer() { delete [] m_data; } /// copy a contiguous block into the buffer void put( const void* data, std::size_t size ) { memcpy( m_put, data, size ); m_put += size; } /// put a single value into the buffer template< typename T > void put( const T& t ) { std::size_t size = sizeof( T ); put( &t, size ); } /// copy a contiguous block of data from the buffer to an already /// allocated location void tell( void* out, std::size_t size ) { memcpy( out, m_tell, size ); m_tell += size; } /// Copy a single value into the buffer. template< typename T > T tell() { std::size_t tsize = sizeof( T ); T tmp; tell( &tmp, tsize ); return tmp; } std::size_t size() const { return m_size; } char* pointer() { return m_data; } void reset() { m_put = m_data; m_tell = m_data; } }; </code> We haven't yet called on the Xdmf API to do anything, the Buffer class is just a utility that we will use later. Now, we write our callback class that will customize the process of opening, reading, writing, and closing the heavy dataset. Since our communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback, XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes has a single virtual method that takes a pointer to a XdmfHeavyData and the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close, XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods. <code> /// Callback implements parallel IO by communicating to process 0 class CommunicationCallback : public XdmfOpenCallback, public XdmfWriteCallback, public XdmfCloseCallback, public XdmfReadCallback { private: int mCommRank; int mCommSize; public: /// Constructor initializes the Number of processors and local process /// ID. CommunicationCallback() { MPI_Comm_size( MPI_COMM_WORLD, &mCommSize ); MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank ); } /// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going /// to read or write, so only rank 0 will open the file. XdmfInt32 DoOpen( XdmfHeavyData* ds, XdmfConstString name, XdmfConstString access ) { if ( mCommRank == 0 ) { // Call the actual DoOpen method from XdmfHeavyData return ds->DoOpen( name, access ); } else { // Not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0 /// needs to do anything. XdmfInt32 DoClose( XdmfHeavyData* ds ) { if ( mCommRank == 0 ) { // Call the heavy dataset's native close method. return ds->DoClose(); } else { // not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfWriteCallback::DoWrite. If the local /// process ID is 0, then we expect to receive data from everyone /// else. Otherwise, we send data. Rank 0 does all of the writing. XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array ) { // This implementation assumes process 0 has the same data // size as everyone else // set up a stream buffer that is large enough to hold the data to // be sent or received. We require enough space for the rank, // start, stride, and count for the array plus enough space to hold // the actual array data. XdmfInt64 start[1], stride[1], count[1]; XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count ); std::size_t slab_info_size = sizeof( XdmfInt32 ) // slab rank + slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count Buffer buf( slab_info_size + array->GetCoreLength() ); // If the local process ID is nonzero, pack the buffer and send to // process 0. if ( mCommRank != 0 ) { // copy rank and slab information into the buffer. buf.put( slab_rank ); for ( int i = 0; i < slab_rank; ++i ) { buf.put( start[i] ); buf.put( stride[i] ); buf.put( count[i] ); } // copy the actual data into the buffer. buf.put( array->GetDataPointer(), array->GetCoreLength() ); // send to rank 0 in the global communicator. MPI_Send( buf.pointer(), buf.size(), MPI_BYTE, 0, 0, MPI_COMM_WORLD ); } else { // Local process ID is 0, so we write local data then receive and // write remote data. // first, it's easy to write the local data ds->DoWrite( array ); int processes_received = 1; // local data for process 0 is written // loop until the data for all processes has been received. while ( processes_received < mCommSize ) { // Fill the buffer with incoming data. We are assuming here // that all processes contain the same amount of data. MPI_Recv( buf.pointer(), buf.size(), MPI_BYTE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, 0 ); processes_received++; // unpack the buffer buf.reset(); // reset the stream pointer to the beginning // we mean rank in the linear algebra sense here slab_rank = buf.tell< XdmfInt32 >(); // start, stride, and count are next. for( int i = 0; i < slab_rank; ++i ) { start[i] = buf.tell< XdmfInt64 >(); stride[i] = buf.tell< XdmfInt64 >(); count[i] = buf.tell< XdmfInt64 >(); } // select the correct hyper slab in the heavy data set. ds->SelectHyperSlab( start, stride, count ); // allocate an array to hold the off-core data. XdmfArray* recv = new XdmfArray; recv->CopyShape( array ); // place the received data into the array. buf.tell( recv->GetDataPointer(), recv->GetCoreLength() ); // write the off core data to the dataset by calling the heavy // data's DoWrite method. ds->DoWrite( recv ); delete recv; } } return XDMF_SUCCESS; } /// Reimplemented from XdmfReadCallback::DoRead. Read the data from a /// heavy data source into an array only if the local process ID is 0. /// Otherwise, do nothing. XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array ) { if ( mCommRank == 0 ) { // defer to the actual heavy data implementation of DoRead. return ds->DoRead( array ); } else { // return an empty array. return NULL; } } }; // end of class CommunicationCallback </code> One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well. Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip. <code> char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI"; int main( int argc, char* argv[] ) { // Initialize MPI MPI_Init( &argc, &argv ); // determine the local process ID int rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // Create an HDF dataset to write out to. XdmfHDF* H5 = new XdmfHDF(); // Attach an instance of the CommunicationCallback class defined above // to customize opening, writing, and closing the dataset. CommunicationCallback* cb = new CommunicationCallback; H5->setOpenCallback( cb ); H5->setWriteCallback( cb ); H5->setCloseCallback(cb ); // Allocate an array of size 25 and fill it with values depending // on the local process ID (process 0 has 0-24, process 1 has // 25-49,...) XdmfArray* MyData = new XdmfArray(); MyData->SetNumberType( XDMF_FLOAT32_TYPE ); MyData->SetNumberOfElements( 25 ); MyData->Generate( rank * 25, rank*25 + 24 ); // Set the dataset's type to the array's type H5->CopyType( MyData ); // Set up the dimensions of the dataset. XdmfInt64 dims[1]; dims[0] = 100; H5->SetShape( 1, dims ); // Set up the hyper slab for the dataset. Each process will select a // distinct portion of the dataset (process 0 has 0-24, process 1 // 25-49,...) XdmfInt64 start[1], stride[1], count[1]; start[0] = rank * 25; stride[0] = 1; count[0] = 25; // select the slab in the dataset corresponding to the local process. H5->SelectHyperSlab( start, stride, count ); // Open the dataset. H5->Open( kDatasetName, "w" ); // Write the array. H5->Write( MyData ); // Close the dataset. H5->Close(); // writing is complete, now we have a quick test to ensure the data // survives a round trip. bool failure = false; // Create a new dataset to read from XdmfHDF* H5In = new XdmfHDF(); // Use the same callback. H5In->setReadCallback( cb ); H5In->setOpenCallback( cb ); H5In->setCloseCallback( cb ); // Open the dataset for reading. H5In->Open( kDatasetName, "r" ); // Read the data into an array. XdmfArray* result = H5In->Read(); // if the read was successful, make sure the values for all processes // are in the file. if ( result ) { for ( size_t i = 0; i < 100; ++i ) { float value = result->GetValueAsFloat32( i ); std::cout << i << " " << value << std::endl; failure = ( value != i ); } } MPI_Finalize(); delete H5; delete cb; delete MyData; delete H5In; delete result; if ( failure ) { return -1; } else { return 0; } }; </code> Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree. bd3e519c7b07a12a8752f3146c2ba6515643d79f 69 66 2009-06-26T16:21:42Z Jerry 2 wikitext text/x-wiki (code, example and description provided by Will Dicharry) === Controlling the I/O process for XdmfHeavyData === The XDMF API provides a customization point to allow the heavy data sets to be written in a certain manner, depending on the application environment and independent of the heavy dataset format. New I/O strategies can be implemented by subclassing the callback classes defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes. This method has the advantage of applying a common strategy to any XdmfHeavyData subclass. The system works in the following way: XdmfHeavyData contains the non-virtual methods Open, Close, Read, and Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite. XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment. In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely. === Example === Suppose we have an MPI environment with 4 processes. Each process contains part of an array with 100 values numbered 0 to 99; process 0 with items 0-24, process 1 with items 25-49, etc. We would like to write this data to a single HDF file containing a single array of 100 values, stored in increasing numerical order. To do this, we will communicate all of the data to process 0 and let process 0 handle the actual output of the array. We start by including the necessary headers and defining a very simple stream buffer utility class that simplifies encoding and decoding data between processes: <code> #include <mpi.h> #include <XdmfArray.h> #include <XdmfHDF.h> /// Simple memory buffer implementation that keeps track of it's stream pointer. class Buffer { private: std::size_t m_size; char* m_data; char* m_put; char* m_tell; public: Buffer( std::size_t size ) : m_size( size ), m_data( new char[size] ), m_put( m_data ), m_tell( m_data ) {} ~Buffer() { delete [] m_data; } /// copy a contiguous block into the buffer void put( const void* data, std::size_t size ) { memcpy( m_put, data, size ); m_put += size; } /// put a single value into the buffer template< typename T > void put( const T& t ) { std::size_t size = sizeof( T ); put( &t, size ); } /// copy a contiguous block of data from the buffer to an already /// allocated location void tell( void* out, std::size_t size ) { memcpy( out, m_tell, size ); m_tell += size; } /// Copy a single value into the buffer. template< typename T > T tell() { std::size_t tsize = sizeof( T ); T tmp; tell( &tmp, tsize ); return tmp; } std::size_t size() const { return m_size; } char* pointer() { return m_data; } void reset() { m_put = m_data; m_tell = m_data; } }; </code> We haven't yet called on the Xdmf API to do anything, the Buffer class is just a utility that we will use later. Now, we write our callback class that will customize the process of opening, reading, writing, and closing the heavy dataset. Since our communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback, XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes has a single virtual method that takes a pointer to a XdmfHeavyData and the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close, XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods. <code> /// Callback implements parallel IO by communicating to process 0 class CommunicationCallback : public XdmfOpenCallback, public XdmfWriteCallback, public XdmfCloseCallback, public XdmfReadCallback { private: int mCommRank; int mCommSize; public: /// Constructor initializes the Number of processors and local process /// ID. CommunicationCallback() { MPI_Comm_size( MPI_COMM_WORLD, &mCommSize ); MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank ); } /// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going /// to read or write, so only rank 0 will open the file. XdmfInt32 DoOpen( XdmfHeavyData* ds, XdmfConstString name, XdmfConstString access ) { if ( mCommRank == 0 ) { // Call the actual DoOpen method from XdmfHeavyData return ds->DoOpen( name, access ); } else { // Not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0 /// needs to do anything. XdmfInt32 DoClose( XdmfHeavyData* ds ) { if ( mCommRank == 0 ) { // Call the heavy dataset's native close method. return ds->DoClose(); } else { // not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfWriteCallback::DoWrite. If the local /// process ID is 0, then we expect to receive data from everyone /// else. Otherwise, we send data. Rank 0 does all of the writing. XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array ) { // This implementation assumes process 0 has the same data // size as everyone else // set up a stream buffer that is large enough to hold the data to // be sent or received. We require enough space for the rank, // start, stride, and count for the array plus enough space to hold // the actual array data. XdmfInt64 start[1], stride[1], count[1]; XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count ); std::size_t slab_info_size = sizeof( XdmfInt32 ) // slab rank + slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count Buffer buf( slab_info_size + array->GetCoreLength() ); // If the local process ID is nonzero, pack the buffer and send to // process 0. if ( mCommRank != 0 ) { // copy rank and slab information into the buffer. buf.put( slab_rank ); for ( int i = 0; i < slab_rank; ++i ) { buf.put( start[i] ); buf.put( stride[i] ); buf.put( count[i] ); } // copy the actual data into the buffer. buf.put( array->GetDataPointer(), array->GetCoreLength() ); // send to rank 0 in the global communicator. MPI_Send( buf.pointer(), buf.size(), MPI_BYTE, 0, 0, MPI_COMM_WORLD ); } else { // Local process ID is 0, so we write local data then receive and // write remote data. // first, it's easy to write the local data ds->DoWrite( array ); int processes_received = 1; // local data for process 0 is written // loop until the data for all processes has been received. while ( processes_received < mCommSize ) { // Fill the buffer with incoming data. We are assuming here // that all processes contain the same amount of data. MPI_Recv( buf.pointer(), buf.size(), MPI_BYTE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, 0 ); processes_received++; // unpack the buffer buf.reset(); // reset the stream pointer to the beginning // we mean rank in the linear algebra sense here slab_rank = buf.tell< XdmfInt32 >(); // start, stride, and count are next. for( int i = 0; i < slab_rank; ++i ) { start[i] = buf.tell< XdmfInt64 >(); stride[i] = buf.tell< XdmfInt64 >(); count[i] = buf.tell< XdmfInt64 >(); } // select the correct hyper slab in the heavy data set. ds->SelectHyperSlab( start, stride, count ); // allocate an array to hold the off-core data. XdmfArray* recv = new XdmfArray; recv->CopyShape( array ); // place the received data into the array. buf.tell( recv->GetDataPointer(), recv->GetCoreLength() ); // write the off core data to the dataset by calling the heavy // data's DoWrite method. ds->DoWrite( recv ); delete recv; } } return XDMF_SUCCESS; } /// Reimplemented from XdmfReadCallback::DoRead. Read the data from a /// heavy data source into an array only if the local process ID is 0. /// Otherwise, do nothing. XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array ) { if ( mCommRank == 0 ) { // defer to the actual heavy data implementation of DoRead. return ds->DoRead( array ); } else { // return an empty array. return NULL; } } }; // end of class CommunicationCallback </code> One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well. Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip. <code> char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI"; int main( int argc, char* argv[] ) { // Initialize MPI MPI_Init( &argc, &argv ); // determine the local process ID int rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // Create an HDF dataset to write out to. XdmfHDF* H5 = new XdmfHDF(); // Attach an instance of the CommunicationCallback class defined above // to customize opening, writing, and closing the dataset. CommunicationCallback* cb = new CommunicationCallback; H5->setOpenCallback( cb ); H5->setWriteCallback( cb ); H5->setCloseCallback(cb ); // Allocate an array of size 25 and fill it with values depending // on the local process ID (process 0 has 0-24, process 1 has // 25-49,...) XdmfArray* MyData = new XdmfArray(); MyData->SetNumberType( XDMF_FLOAT32_TYPE ); MyData->SetNumberOfElements( 25 ); MyData->Generate( rank * 25, rank*25 + 24 ); // Set the dataset's type to the array's type H5->CopyType( MyData ); // Set up the dimensions of the dataset. XdmfInt64 dims[1]; dims[0] = 100; H5->SetShape( 1, dims ); // Set up the hyper slab for the dataset. Each process will select a // distinct portion of the dataset (process 0 has 0-24, process 1 // 25-49,...) XdmfInt64 start[1], stride[1], count[1]; start[0] = rank * 25; stride[0] = 1; count[0] = 25; // select the slab in the dataset corresponding to the local process. H5->SelectHyperSlab( start, stride, count ); // Open the dataset. H5->Open( kDatasetName, "w" ); // Write the array. H5->Write( MyData ); // Close the dataset. H5->Close(); // writing is complete, now we have a quick test to ensure the data // survives a round trip. bool failure = false; // Create a new dataset to read from XdmfHDF* H5In = new XdmfHDF(); // Use the same callback. H5In->setReadCallback( cb ); H5In->setOpenCallback( cb ); H5In->setCloseCallback( cb ); // Open the dataset for reading. H5In->Open( kDatasetName, "r" ); // Read the data into an array. XdmfArray* result = H5In->Read(); // if the read was successful, make sure the values for all processes // are in the file. if ( result ) { for ( size_t i = 0; i < 100; ++i ) { float value = result->GetValueAsFloat32( i ); std::cout << i << " " << value << std::endl; failure = ( value != i ); } } MPI_Finalize(); delete H5; delete cb; delete MyData; delete H5In; delete result; if ( failure ) { return -1; } else { return 0; } }; </code> Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree. ea4acf12b0ade3117524519bbb92e270521b3fe0 Update proposal 2008 08 17 0 13 70 2009-08-17T14:21:36Z Dave.demarle 5 New page: In Early 2007, XDMF underwent a substantial revision. What was the original library we now call XDMF1, and the new version is called XDMF2. The move was enabled by a switch to the libxml2 ... wikitext text/x-wiki In Early 2007, XDMF underwent a substantial revision. What was the original library we now call XDMF1, and the new version is called XDMF2. The move was enabled by a switch to the libxml2 xml parsing library. Changes to XDMF included: 1. Replace expat + Xdmf functions with libxml2 2. Support XPath 3. XdmfStructure + XdmfTrasform have been merged into XdmfDataItem 4. DataItem support hierarchical structure 5. Grids support hierarchical structure 6. Added support for Quadratic elements 7. Added support for mixed topologies 8. Added XdmfInformation - Application specific data 9. Added Writing capabilities to Xmdf lib. The state of the DOM is accurately reflected in the XML 10. All XDMF XML Elements now have an XdmfObject representation 11. Adding DSM 12. Update from hdf 1.6.2 to hdf 1.6.5 At the same time VTK's (and thus ParaView's) interface to XDMF was partially updated to use the new library. That is, vtkXDMFReader was upgraded to recognize the XDMF2's new syntax and directly produce composite data sets instead of multiple outputs, as well as to understand quadratic elements and mixed topologies and produce the corresponding vtk data structures. Meanwhile, vtkXDMFWriter was only upgraded enough to use XDMF2 in a backwards compatibility mode. Since that time important new features have been added to XDMF2. Although these features exist in the library, not all of them are useable in the vtkXDMFReader, and even fewer are useable in the vtkXDMFReader. The new features include: temporal support - Jerry and Biddiscombe (Early 2008) additional cell types - CSimsoft (Early 2008) ghost levels - Chris Kees (May 2008) sql - Jerry (?) compression - Ian Curlington (May 2008) parallel "strategies" - Will Dicharry (Jun 2008) in place row/major column reordering - Dominik Szczerba (Jun 2008) better hdf version independence - Jerry (Jun 2008) Additionally interest for the following features exists: units annotations tabular data (info vis) out of core row/major reordering SIL interface static geometry and topology time varying data optimizations wildcard specification Finally, a full suit of web resources for XDMF would be beneficial to the community at large. The most important is comprehensive regression testing. All fundamental data types should be regularly tested so that we get decent coverage of the libraries capabilities, and so that new users have a set of examples to work from. Additional resources such as a bug tracker and online would doxygen documentation are desireable. WRITER PLAN OF ACTION Produce hierachical data items when given composite data object inputs produce full set of data types that reader recognizes add support for time parallel efficiency 20458af21292ef248c179771f4d9b112e5cac356 71 70 2009-08-21T15:59:49Z Dave.demarle 5 update with specifics now that I've actually started working on it wikitext text/x-wiki In Early 2007, XDMF underwent a substantial revision. What was the original library we now call XDMF1, and the new version is called XDMF2. The move was enabled by a switch to the libxml2 xml parsing library. Changes to XDMF included: 1. Replace expat + Xdmf functions with libxml2 2. Support XPath 3. XdmfStructure + XdmfTrasform have been merged into XdmfDataItem 4. DataItem support hierarchical structure 5. Grids support hierarchical structure 6. Added support for Quadratic elements 7. Added support for mixed topologies 8. Added XdmfInformation - Application specific data 9. Added Writing capabilities to Xmdf lib. The state of the DOM is accurately reflected in the XML 10. All XDMF XML Elements now have an XdmfObject representation 11. Adding DSM 12. Update from hdf 1.6.2 to hdf 1.6.5 At the same time VTK's (and thus ParaView's) interface to XDMF was partially updated to use the new library. That is, vtkXDMFReader was upgraded to recognize the XDMF2's new syntax (see 4 and 5 above) and directly produce composite data sets instead of multiple outputs. Meanwhile, vtkXDMFWriter was only upgraded enough to use XDMF2 in a backwards compatibility mode. The writer does not understand vtkCompositeDataSet types and still expects to be given complex data in the form of multiple inputs - a legacy of the old ParaView multi-part architecture. Additionally the writer is restricted to a few input dataset structures, because it does not make use of XDMF2's support for mixed topologies. Work is now underway to upgrade the vtk writer, to bring it up to date with the library. See below. After the initial upgrade to XDMF2, important new features have been added to XDMF. Although these features exist in the library, not all of them are useable in the vtkXDMFReader, and even fewer are useable in the vtkXDMFWriter. The new features include: temporal support - Jerry and Biddiscombe (Early 2008) additional cell types - CSimsoft (Early 2008) ghost levels - Chris Kees (May 2008) sql heavy data - Jerry (?) compression - Ian Curlington (May 2008) parallel "strategies" - Will Dicharry (Jun 2008) in place row/major column reordering - Dominik Szczerba (Jun 2008) better hdf version independence - Jerry (Jun 2008) A survey of traffic on the XDMF mailing list shows that there is demand for the following additional features: unit annotations tabular data (info vis) out of core row/major reordering SIL interface to composite Data static geometry and topology time varying data optimizations wildcard specification Finally, I personally think that a full suite of web resources for XDMF would be beneficial to the community at large. These would include bug tracker, doxygen documentation, and regression testing. The most urgent is the need for comprehensive regression testing. The tests should cover at least the important configurations for XDMF, and the fundamental data types. The tests would exist to cover the libraries important features, to ensure that they continue to work as developers improve the library, and also to provide a set of working examples for new users. The configurations of the library that could be tested are the combinations of the following options: mpi vtk system hdf5 system libxml2 system zlib python run from install/run from build directory However only a handful of the combinations need to be tested. For example, it appears that python=ON and MPI=OFF do not compile today. == Writer == Objectives: produce hierachical data items when given composite data object inputs produce full set of data types that reader recognizes add support for time parallel efficiency Architecture: The plan for upgrading the writer is to introduce a new writer class, and to keep the the existing writer functional, until is can be deprecated and removed. The new writer will be written with these two objectives. First, it is desireable to minimize in memory copies or raw data, using pointer sharing as much as possible to reduce memory requirements for large data processing. Second, it is desireable to leave as much work to the XDMF library itself as possible. The existing writer was written before the xdmf2, and thus manually writes out strings to produce XML elements, because XDMF1 did not have support for writing (see 9 above). The writer then, will be responsible for examining its input vtkDataObject (note, not plural, we will not support writing multiple objects simultaneously), traversing the tree structure if that object is a composite one, and at each node in the tree, making calls the the XDMF library to convert the in memory VTK data structures into XDMF elements, where each element is configured appropriately and given access to the in memory data array addresses. The initial design will not support parallelism, or temporal support. Once the static and serial code is proven these features will be added. Temporal support will simply involve obtaining the time domain from the input, and then if the input is time varying, beginning the XDMF structure with a temporal collection. Parallel support can mean several things. In parallel, each processor may produce its own file, or all might produce a single file either synchronously or in a round robin fasion. Additionally the data or the xml elements for the file could be shared or transfered between processors. The optimal strategy depends upon the data and platform, most importantly whether the filesystem is independent, networked or parallel filesystem. Thus we may support one or more of these parallel options, and the choice will be made after the writer is functioning properly. 1fa3643037b65bed6020417f836559ff8aed8825 72 71 2009-08-24T14:24:44Z Dave.demarle 5 wikitext text/x-wiki In Early 2007, XDMF underwent a substantial revision. What was the original library we now call XDMF1, and the new version is called XDMF2. The move was enabled by a switch to the libxml2 xml parsing library. Changes to XDMF included: 1. Replace expat + Xdmf functions with libxml2 2. Support XPath 3. XdmfStructure + XdmfTrasform have been merged into XdmfDataItem 4. DataItem support hierarchical structure 5. Grids support hierarchical structure 6. Added support for Quadratic elements 7. Added support for mixed topologies 8. Added XdmfInformation - Application specific data 9. Added Writing capabilities to Xmdf lib. The state of the DOM is accurately reflected in the XML 10. All XDMF XML Elements now have an XdmfObject representation 11. Adding DSM 12. Update from hdf 1.6.2 to hdf 1.6.5 At the same time VTK's (and thus ParaView's) interface to XDMF was partially updated to use the new library. That is, vtkXDMFReader was upgraded to recognize the XDMF2's new syntax (see 4 and 5 above) and directly produce composite data sets instead of multiple outputs. Meanwhile, vtkXDMFWriter was only upgraded enough to use XDMF2 in a backwards compatibility mode. The writer does not understand vtkCompositeDataSet types and still expects to be given complex data in the form of multiple inputs - a legacy of the old ParaView multi-part architecture. Additionally the writer is restricted to a few input dataset structures, because it does not make use of XDMF2's support for mixed topologies. Work is now underway to upgrade the vtk writer, to bring it up to date with the library. See below. After the initial upgrade to XDMF2, important new features have been added to XDMF. Although these features exist in the library, not all of them are useable in the vtkXDMFReader, and even fewer are useable in the vtkXDMFWriter. The new features include: temporal support - Jerry and Biddiscombe (Early 2008) additional cell types - CSimsoft (Early 2008) ghost levels - Chris Kees (May 2008) sql heavy data - Jerry (?) compression - Ian Curlington (May 2008) parallel "strategies" - Will Dicharry (Jun 2008) in place row/major column reordering - Dominik Szczerba (Jun 2008) better hdf version independence - Jerry (Jun 2008) A survey of traffic on the XDMF mailing list shows that there is demand for the following additional features: unit annotations tabular data (info vis) out of core row/major reordering SIL interface to composite Data static geometry and topology time varying data optimizations wildcard specification Finally, I personally think that a full suite of web resources for XDMF would be beneficial to the community at large. These would include bug tracker, doxygen documentation, and regression testing. The most urgent is the need for comprehensive regression testing. The tests should cover at least the important configurations for XDMF, and the fundamental data types. The tests would exist to cover the library's important features, to ensure that they continue to work as developers improve the library, and also to provide a set of working examples for new users. The configurations of the library that could be tested are the combinations of the following options: mpi vtk system hdf5 system libxml2 system zlib python run from install/run from build directory However only a handful of the combinations need to be tested. The need for testing is corroborated by the fact that as of today it appears that the combination of python=ON and MPI=OFF does not compile. == Writer == Objectives: produce hierachical data items when given composite data object inputs produce full set of data types that reader recognizes add support for time parallel efficiency Architecture: The plan for upgrading the writer is to introduce a new writer class, and to keep the the existing writer functional, until is can be deprecated and removed. The new writer will be written with these two objectives. First, it is desirable to minimize in memory copies or raw data, using pointer sharing as much as possible to reduce memory requirements for large data processing. Second, it is desirable to leave as much work to the XDMF library itself as possible. The existing writer was written before the xdmf2 and manually writes out strings to produce XML elements. Since XDMF2 has support for writing (see 9 above), the new writer should use it directly. The writer then, will be responsible for examining its input vtkDataObject (note, not plural, we will not support writing multiple objects simultaneously), traversing the tree structure if that object is a composite one, and at each node in the tree, making calls the the XDMF library to convert the in memory VTK data structures into XDMF elements, where each element is configured appropriately and given access to the in memory data array addresses. The initial design will not support parallelism, or temporal support. Once the static and serial code is proven these features will be added. Temporal support will simply involve obtaining the time domain from the input, and then if the input is time varying, beginning the XDMF structure with a temporal collection. Parallel support can mean several things. In parallel, each processor may produce its own file, or all might produce a single file either synchronously or in a round robin fasion. Additionally the data or the xml elements for the file could be shared or transfered between processors. The optimal strategy depends upon the data and platform, most importantly whether the filesystem is independent, networked or parallel filesystem. Thus we may support one or more of these parallel options, and the choice will be made after the writer is functioning properly. 24224fe9ff44a608033320a97c196e241085638d Xdmf::New() 0 14 75 2010-01-07T15:16:23Z Jerry 2 New page: After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full fea... wikitext text/x-wiki After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full featured and customizable API for producing Xdmf in parallel. The '''''existing XML format will most likely stay the same''''' with a few additions. So if you're currently producing Xdmf data outside the API this will have minimal impact. Also if you're just reading Xdmf as a file format this will have minimal impact as well. '''Smart Pointers''' Smart pointers in C++ will help eliminate memory leaks and double free problems. Most likely the implementation will be intrusive smart pointers with reference counting. It is expected that moving to smart pointers will have minimal effect on performance while greatly increasing the efficiency of resource management. '''API changes/additions for sharing and producing data in parallel''' While reading Xdmf is well defined and straight forward in the current API, producing and sharing the underlying geometric and computed data can become complex (particularly in a parallel computation). Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.) it is best to allow the application to determine the proper representation and the most efficient method to achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible mechanism. Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at: [http://xdm.googlecode.com/svn/trunk] '''Remove libxml2 dependencies from base objects - use containers''' Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2. A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and decouple the generation of the XML using a visitor pattern. This would also allow for various other representations of the light data as they become necessary. '''Better Fortran Support''' Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion. To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other. Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least there should be transposing support with options. '''Additional Topology Support''' Additional Topology types '''Static Geometry, Dynamic Attribute Support''' '''Much more testing, example code, and example datasets''' a9c64182962c42b909529cd13e9fe17a4d4f8c6f 76 75 2010-01-07T15:31:24Z Jerry 2 wikitext text/x-wiki After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full featured and customizable API for producing Xdmf in parallel. The '''''existing XML format will most likely stay the same''''' with a few additions. So if you're currently producing Xdmf data outside the API this will have minimal impact. Also if you're just reading Xdmf as a file format this will have minimal impact as well. '''Smart Pointers''' Smart pointers in C++ will help eliminate memory leaks and double free problems. Most likely the implementation will be intrusive smart pointers with reference counting. It is expected that moving to smart pointers will have minimal effect on performance while greatly increasing the efficiency of resource management. '''API changes/additions for sharing and producing data in parallel''' While reading Xdmf is well defined and straight forward in the current API, producing and sharing the underlying geometric and computed data can become complex (particularly in a parallel computation). Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.) it is best to allow the application to determine the proper representation and the most efficient method to achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible mechanism. Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at: [http://xdm.googlecode.com/svn/trunk] '''Remove libxml2 dependencies from base objects - use containers''' Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2. A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and decouple the generation of the XML using a visitor pattern. This would also allow for various other representations of the light data as they become necessary. '''Better Fortran Support''' Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion. To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other. Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least there should be transposing support with options. '''Additional Topology Support''' Additional Topology types '''Static Geometry, Dynamic Attribute Support''' If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items. '''Active Grid an/or Attribute''' Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly during debugging. '''Much more testing, example code, and example datasets''' 599ec846a5752182f4cbb490fb4c54b9bb1f3725 77 76 2010-01-07T15:35:32Z Jerry 2 wikitext text/x-wiki After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full featured and customizable API for producing Xdmf in parallel. The '''''existing XML format will most likely stay the same''''' with a few additions. So if you're currently producing Xdmf data outside the API this will have minimal impact. Also if you're just reading Xdmf as a file format this will have minimal impact as well. '''Smart Pointers''' Smart pointers in C++ will help eliminate memory leaks and double free problems. Most likely the implementation will be intrusive smart pointers with reference counting. It is expected that moving to smart pointers will have minimal effect on performance while greatly increasing the efficiency of resource management. '''API changes/additions for sharing and producing data in parallel''' While reading Xdmf is well defined and straight forward in the current API, producing and sharing the underlying geometric and computed data can become complex (particularly in a parallel computation). Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.) it is best to allow the application to determine the proper representation and the most efficient method to achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible mechanism. Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at: [http://xdm.googlecode.com/svn/trunk] '''Remove libxml2 dependencies from base objects - use containers''' Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2. A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and decouple the generation of the XML using a visitor pattern. This would also allow for various other representations of the light data as they become necessary. '''Better Fortran Support''' Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion. To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other. Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least there should be transposing support with options. '''Additional Topology Support''' Additional Topology types '''Static Geometry, Dynamic Attribute Support''' If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items. '''Active Grid an/or Attribute''' Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly during debugging. '''Much more testing, example code, and example datasets''' CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things such as parallel I/O, ghost cells, Collections, etc. 1127e8c657670471eeb61b95cdc90354c4a83c87 78 77 2010-01-07T15:37:52Z Jerry 2 wikitext text/x-wiki After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full featured and customizable API for producing Xdmf in parallel. The <span style='color:red'>'''''existing XML format will most likely stay the same'''''</span> with a few additions. So if you're currently producing Xdmf data outside the API this will have minimal impact. Also if you're just reading Xdmf as a file format this will have minimal impact as well. '''Smart Pointers''' Smart pointers in C++ will help eliminate memory leaks and double free problems. Most likely the implementation will be intrusive smart pointers with reference counting. It is expected that moving to smart pointers will have minimal effect on performance while greatly increasing the efficiency of resource management. '''API changes/additions for sharing and producing data in parallel''' While reading Xdmf is well defined and straight forward in the current API, producing and sharing the underlying geometric and computed data can become complex (particularly in a parallel computation). Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.) it is best to allow the application to determine the proper representation and the most efficient method to achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible mechanism. Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at: [http://xdm.googlecode.com/svn/trunk] '''Remove libxml2 dependencies from base objects - use containers''' Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2. A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and decouple the generation of the XML using a visitor pattern. This would also allow for various other representations of the light data as they become necessary. '''Better Fortran Support''' Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion. To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other. Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least there should be transposing support with options. '''Additional Topology Support''' Additional Topology types '''Static Geometry, Dynamic Attribute Support''' If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items. '''Active Grid an/or Attribute''' Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly during debugging. '''Much more testing, example code, and example datasets''' CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things such as parallel I/O, ghost cells, Collections, etc. 1b14e1864eb866bc0cf94a13db837d6c929b0a94 79 78 2010-01-07T15:41:42Z Jerry 2 wikitext text/x-wiki After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full featured and customizable API for producing Xdmf in parallel. The <span style='color:red'>'''''existing XML format will most likely stay the same'''''</span> with a few additions. So if you're currently producing Xdmf data outside the API this will have minimal impact. Also if you're just reading Xdmf as a file format this will have minimal impact as well. Here's a current running list of proposed changes/additions : '''Smart Pointers''' Smart pointers in C++ will help eliminate memory leaks and double free problems. Most likely the implementation will be intrusive smart pointers with reference counting. It is expected that moving to smart pointers will have minimal effect on performance while greatly increasing the efficiency of resource management. '''API changes/additions for sharing and producing data in parallel''' While reading Xdmf is well defined and straight forward in the current API, producing and sharing the underlying geometric and computed data can become complex (particularly in a parallel computation). Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.) it is best to allow the application to determine the proper representation and the most efficient method to achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible mechanism. Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at: [http://xdm.googlecode.com/svn/trunk SVN Repository at GoogleCode] '''Remove libxml2 dependencies from base objects - use containers''' Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2. A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and decouple the generation of the XML using a visitor pattern. This would also allow for various other representations of the light data as they become necessary. '''Better Fortran Support''' Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion. To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other. Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least there should be transposing support with options. '''Additional Topology Support''' Additional Topology types '''Static Geometry, Dynamic Attribute Support''' If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items. '''Active Grid an/or Attribute''' Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly during debugging. '''Much more testing, example code, and example datasets''' CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things such as parallel I/O, ghost cells, Collections, etc. b32c1ecc80d72312dbc2646f50cca3e8e87eec86 80 79 2010-01-07T15:46:21Z Jerry 2 wikitext text/x-wiki After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full featured and customizable API for producing Xdmf in parallel. The <span style='color:red'>'''''existing XML format will most likely stay the same'''''</span> with a few additions. So if you're currently producing Xdmf data outside the API this will have minimal impact. Also if you're just reading Xdmf as a file format this will have minimal impact as well. Here's a current running list of proposed changes/additions : '''Smart Pointers''' Smart pointers in C++ will help eliminate memory leaks and double free problems. Most likely the implementation will be intrusive smart pointers with reference counting. It is expected that moving to smart pointers will have minimal effect on performance while greatly enhancing resource management. '''API changes/additions for sharing and producing data in parallel''' While accessing simple Xdmf is well defined and straight forward in the current API, producing and sharing the underlying geometric and computed data can become complex (particularly in a parallel computation). Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.) it is best to allow the application to determine the proper representation and the most efficient method to achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible mechanism. Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at: [http://xdm.googlecode.com/svn/trunk SVN Repository at GoogleCode] '''Remove libxml2 dependencies from base objects - use containers''' Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2. A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and decouple the generation of the XML using a visitor pattern. This would also allow for various other representations of the light data as they become necessary. '''Better Fortran Support''' Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion. To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other. Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least there should be transposing support with options. '''Additional Topology Support''' Additional Topology types '''Static Geometry, Dynamic Attribute Support''' If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items. '''Active Grid an/or Attribute''' Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly during debugging. '''Much more testing, example code, and example datasets''' CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things such as parallel I/O, ghost cells, Collections, etc. ee244829e0c94db6daf3b1a8d1a4dbd250c35d4a 81 80 2010-01-07T15:53:46Z Jerry 2 wikitext text/x-wiki After some discussion with several interested parties, we've decided to re-work Xdmf a bit. Most of the changes involve the API, particularly moving to smart pointers and a more full featured and customizable API for producing Xdmf in parallel. The <span style='color:red'>'''''existing XML format will most likely stay the same'''''</span> with a few additions. So if you're currently producing Xdmf data outside the API this will have minimal impact. Also if you're just reading Xdmf as a file format this will have minimal impact as well. Here's a current running list of proposed changes/additions : '''Smart Pointers''' Smart pointers in C++ will help eliminate memory leaks and double free problems. Most likely the implementation will be intrusive smart pointers with reference counting. It is expected that moving to smart pointers will have minimal effect on performance while greatly enhancing resource management. '''API changes/additions for sharing and producing data in parallel''' While accessing simple Xdmf is well defined and straight forward in the current API, producing and sharing the underlying geometric and computed data can become complex (particularly in a parallel computation). Since there can be several ways to represent the same data (a single large uniform grid, collections, etc.) it is best to allow the application to determine the proper representation and the most efficient method to achieve the result (generate the heavy data and collect the associated XML). What is needed is a more flexible mechanism. Will Dicharry (Stellar Science Ltd Co) has proposed an API that looks very promising. If you'd like to take a look, the code is available at: [http://xdm.googlecode.com/svn/trunk SVN Repository at GoogleCode] '''Remove libxml2 dependencies from base objects - use containers''' Currently, Xdmf is tightly tied to libxml2, actually using the library to store state information. This leads to instances where data in the Xdmf objects can become out of sync with the data in the XML representation in libxml2. A better approach is probably to let the Xdmf objects store all necessary data internally using C++ containers and decouple the generation of the XML using a visitor pattern. This would also allow for various other representations of the light data as they become necessary. '''Better Fortran Support''' Xdmf is currently 'C'-centric in that array dimensions are assumed to be row-major and data is accessed in that fashion. To properly use Xdmf with arrays in Fortran, which is column-major, the arrays need to be transposed on one end or the other. Transposing in memory may not work for huge arrays and transposing during I/O may incur significant overhead. At very least there should be transposing support with options. '''Additional Topology Support''' Additional Topology types '''Static Geometry, Dynamic Attribute Support''' If the Topology and/or Geometry does not change over time, it would be more efficient to cache that information. The current implementation assumes that every <Grid> is independent and re-reads the Topo/Geo. One idea to use XPointers in XML and mark the <Grid> with an XML attribute that tells Xdmf that it's possible to cache. Another idea is to cache the CData of the <DataItem> (from Dominik Szczerba) to flag identical heavy data items. DSM applications where the Heavy Data location stays constant, but the underlying data changes, must be considered. '''Active Grid an/or Attribute''' Some mechanism to mark a Grid or an Attribute as "active" so, by default, only that one is read. Very efficient, particularly during debugging. '''Much more testing, example code, and example datasets''' CTest as much as possible. Take more advantage of the existing dashboards. Provide many more example datasets and code for things such as parallel I/O, ghost cells, Collections, etc. 85108d2ee3193fa4134b9739344c3a84afc1e668 V3 Road Feature Request 0 15 95 2014-07-25T18:30:16Z Imikejackson 18 Created page with "== Version 3 Feature Request' == '''Implement AttributeType=Matrix''' I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example o..." wikitext text/x-wiki == Version 3 Feature Request' == '''Implement AttributeType=Matrix''' I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example on how to use the Matrix AttributeMatrix. For example I have a triangular surface mesh where each triangle has a (2x1) matrix of values so that each triangle has 2 values. Currently we have to setup a hyper slab for the data array and end up with 2 data items. <Attribute Name="SurfaceMeshFaceLabels (Feature 0)" AttributeType="Scalar" Center="Cell"> <DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 0)" > <DataItem Dimensions="3 2" Format="XML" > 0 0 1 1 757136 1 </DataItem> <DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" > Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </DataItem> </Attribute> <Attribute Name="SurfaceMeshFaceLabels (Feature 1)" AttributeType="Scalar" Center="Cell"> <DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 1)" > <DataItem Dimensions="3 2" Format="XML" > 0 1 1 1 757136 1 </DataItem> <DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" > Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </DataItem> </Attribute> I would rather do something like this: <Attribute Center="Cell" Name="Phases_Matrix" Type="Matrix"> <DataItem Dimensions="2 1" Format="XML" >2 1</DataItem> <DataItem DataType="Int" Dimensions="757136 2" Format="HDF" Precision="4"> Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </Attribute> Or something like that. '''1DCoRectMesh''' I will like to have also something like 1DCORECTMesh, for the moment I Use a 2DCORECTMesh with only 1 point in the second direction. But cant be used with cell data (paraview crash). So I use only point data. 7a2c17595ccee711626227dcb2de59720887fb8f Examples/imagedata 0 16 98 2014-08-19T18:26:04Z Dave.demarle 5 Created page with "The following will read in an array of floats from h5 with the values associated with the points. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:x..." wikitext text/x-wiki The following will read in an array of floats from h5 with the values associated with the points. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Domain> <Grid Name="Particle Images" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" Dimensions="400 300 300"/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Name="Origin" Dimensions="3" NumberType="Float" Precision="4" Format="XML"> 0 0 0 </DataItem> <DataItem Name="Spacing" Dimensions="3" NumberType="Float" Precision="4" Format="XML"> 1 1 1 </DataItem> </Geometry> <Attribute Name="second 0" AttributeType="Scalar" Center="Node"> <DataItem Format="HDF" NumberType="UInt" Precision="2" Dimensions="400 300 300">test.hdf:/images/0/image</DataItem> </Attribute> </Grid> </Domain> </Xdmf> The following will read in an array of floats from h5 with the values associated with the cells. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Domain> <Grid Name="Particle Images" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" Dimensions="401 301 301"/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Name="Origin" Dimensions="3" NumberType="Float" Precision="4" Format="XML"> 0 0 0 </DataItem> <DataItem Name="Spacing" Dimensions="3" NumberType="Float" Precision="4" Format="XML"> 1 1 1 </DataItem> </Geometry> <Attribute Name="second 0" AttributeType="Scalar" Center="Cell"> <DataItem Format="HDF" NumberType="UInt" Precision="2" Dimensions="400 300 300">test.hdf:/images/0/image</DataItem> </Attribute> </Grid> </Domain> </Xdmf> 66a4b28f1cb403370ad45f867904ca30812c61aa Version 2 0 17 100 2014-08-19T18:45:42Z Dave.demarle 5 Created page with "version "2" of Xdmf can be found at: git clone git://xdmf.org/Xdmf.git" wikitext text/x-wiki version "2" of Xdmf can be found at: git clone git://xdmf.org/Xdmf.git 4d8ae04a65e689587ada6abc5ddda0a342af9ab2 Version 1 0 18 101 2014-08-19T18:52:28Z Dave.demarle 5 Created page with "Version "1" of xdmf can be obtained via: cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkou..." wikitext text/x-wiki Version "1" of xdmf can be obtained via: cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf 748054074818604ae71dc7df0b12b7dabe95617a Version 2 0 17 102 100 2014-08-19T18:54:58Z Dave.demarle 5 wikitext text/x-wiki Version "2" of Xdmf can be found at: git clone git://xdmf.org/Xdmf.git The updates to Xdmf in version 2 are summarized in this paper: [http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792] 13e3dd3dbc769427a4d87800a7a5af214b33c8e3 106 102 2014-08-19T19:03:28Z Dave.demarle 5 explain the "pv" branch. wikitext text/x-wiki Version "2" of Xdmf can be found at: git clone git://xdmf.org/Xdmf.git There are two important branches in the repository, "master" and "pv". The "pv" branch was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system. The updates to Xdmf in version 2 are summarized in this paper: [http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792] 6abb690a2f2e5d845cb711c4dcf970238ad1074c 107 106 2014-08-19T19:05:54Z Dave.demarle 5 wikitext text/x-wiki Version "2" of Xdmf can be found at: git clone git://xdmf.org/Xdmf.git There are two important branches in the repository, "master" and "pv". The "pv" branch was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system. The updates to Xdmf in version 2 are summarized in this paper: [http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792] and this podcast [http://www.rce-cast.com/components/com_podcast/media/40RCE-xdmf.mp3] 95345d944cd3ab16c5cc165ea3b3c9407859d800 Version 3 0 19 103 2014-08-19T18:57:57Z Dave.demarle 5 Created page with "Version "3" of Xdmf can be obtained from: git://public.kitware.com/Xdmf2.git The initial plans for changes that went into version 3 are summarized on: [http://xdmf.org/index...." wikitext text/x-wiki Version "3" of Xdmf can be obtained from: git://public.kitware.com/Xdmf2.git The initial plans for changes that went into version 3 are summarized on: [http://xdmf.org/index.php/Xdmf::New()] Additionally, this version added support for Graph types. c50fef82f363ce1ba734ae65b4c7b4c3036d4868 108 103 2014-08-19T19:07:34Z Dave.demarle 5 wikitext text/x-wiki Version "3" of Xdmf can be obtained from: git://public.kitware.com/Xdmf2.git The initial plans for changes that went into version 3 are summarized on: [http://xdmf.org/index.php/Xdmf::New()] The overall goals included better performance and use of modern and more maintainable C++ programming idioms. This version adds a dependence on boost. Additionally, this version added support for Graph types and removed support for the SQL back end. 8b6ad6e00d70679bc0bbd0fe8493c18027041f10 Main Page 0 1 104 99 2014-08-19T18:58:55Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Xdmf::New()|'''What's Next''']] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 6e40e509517f6a677f62e72bacea9b09cbd8d9e8 105 104 2014-08-19T18:59:17Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 89c8982e6d48aed577c1edfc966c58d8df1ff99d 109 105 2014-08-19T19:09:51Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Use XDMF from wrapped languages]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] a51f7be4706ea0346ce8856a1bb8140a41728b82 121 109 2014-08-19T19:29:28Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 89c8982e6d48aed577c1edfc966c58d8df1ff99d 125 121 2014-09-02T15:36:46Z FelipeB 19 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] * [[V2_To_V3|V2 to V3 Transition and bugs]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 11473ec14900229f9484ef61ec2a013c844e7859 144 125 2014-11-07T21:07:22Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Write from Fortran|Xdmf3 Fortran API]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] * [[V2_To_V3|V2 to V3 Transition and bugs]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 869282ac2f9a5431366c3728fe2550cef3c4d384 145 144 2014-11-07T21:07:46Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Xdmf3 Fortran API|Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] * [[V2_To_V3|V2 to V3 Transition and bugs]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 6f37dce2ba7ec34fd340f8aafef86be5b58ce617 Read Xdmf 0 8 110 38 2014-08-19T19:12:14Z Dave.demarle 5 wikitext text/x-wiki == Reading XDMF Data == [[Image:TwoHex.jpg]] The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face. There are values centered at the nodes and at the cell centers. The values for geometry, connectivity, and scalars are all stored directly in the XML file. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf> <Domain> <Grid Name="TestGrid"> <Topology Type="Hexahedron" NumberOfElements="2" > <DataItem Format="XML" DataType="Float" Dimensions="2 8"> 0 1 7 6 3 4 10 9 1 2 8 7 4 5 11 10 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="4 3 3"> 0.0 0.0 1.0 1.0 0.0 1.0 3.0 0.0 2.0 0.0 1.0 1.0 1.0 1.0 1.0 3.0 2.0 2.0 0.0 0.0 -1.0 1.0 0.0 -1.0 3.0 0.0 -2.0 0.0 1.0 -1.0 1.0 1.0 -1.0 3.0 2.0 -2.0 </DataItem> </Geometry> <Attribute Name="NodeValues" Center="Node"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="4 3" > 100 200 300 300 400 500 300 400 500 500 600 700 </DataItem> </Attribute> <Attribute Name="CellValues" Center="Cell"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="2" > 100 200 </DataItem> </Attribute> </Grid> </Domain> </Xdmf> The XML is stored in the file "MyGrid.xmf". The following Python program demonstrated parsing the XML and retrieving the data values. <pre style="color: red">Note this code snippet is from version 2 or 1 and needs updating for xdmf3.</pre> from Xdmf import * dom = XdmfDOM() dom.Parse('MyGrid.xmf') # We now have a tree. Find the one and only Grid element ge = dom.FindElementByPath('/Xdmf/Domain/Grid') grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) # Read Light Data grid.UpdateInformation() # Read Heavy Data which includes Topology and Geometry grid.Update() top = grid.GetTopology() conn = top.GetConnectivity() print 'Values = ', conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print 'Geo Type = ', geo.GetGeometryTypeAsString(), ' # Points = ', geo.GetNumberOfPoints() print 'Points = ', points.GetValues() # for each Attribute, print Light Data and Values for i in range(grid.GetNumberOfAttributes()) : attr = grid.GetAttribute(i) print 'Attribute ', i, ' Name = ', attr.Get('Name') # Attribute HeavyData is not Updated by default # there could potentially be many causing huge IO attr.Update() vals = attr.GetValues() print 'Values ', vals.GetValues() a8bfcce8aed25e197a22acb13f383b6af17d5e57 146 110 2014-11-10T16:43:36Z Burns 17 wikitext text/x-wiki == Reading XDMF Data == [[Image:TwoHex.jpg]] The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face. There are values centered at the nodes and at the cell centers. The values for geometry, connectivity, and scalars are all stored directly in the XML file. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf> <Domain> <Grid Name="TestGrid"> <Topology Type="Hexahedron" NumberOfElements="2" > <DataItem Format="XML" DataType="Float" Dimensions="2 8"> 0 1 7 6 3 4 10 9 1 2 8 7 4 5 11 10 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="4 3 3"> 0.0 0.0 1.0 1.0 0.0 1.0 3.0 0.0 2.0 0.0 1.0 1.0 1.0 1.0 1.0 3.0 2.0 2.0 0.0 0.0 -1.0 1.0 0.0 -1.0 3.0 0.0 -2.0 0.0 1.0 -1.0 1.0 1.0 -1.0 3.0 2.0 -2.0 </DataItem> </Geometry> <Attribute Name="NodeValues" Center="Node"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="4 3" > 100 200 300 300 400 500 300 400 500 500 600 700 </DataItem> </Attribute> <Attribute Name="CellValues" Center="Cell"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="2" > 100 200 </DataItem> </Attribute> </Grid> </Domain> </Xdmf> The XML is stored in the file "MyGrid.xmf". The following Python program demonstrated parsing the XML and retrieving the data values. from Xdmf import * reader = XdmfReader.New() dom = XdmfReader.read('MyGrid.xmf') # We now have a tree. Find the one and only Grid element grid = dom.getUnstruturedGrid(0) top = grid.GetTopology() print 'Values = ', top.getValuesString() # Release values from data when done top.release() geo = grid.GetGeometry() print 'Geo Type = ', geo.getType().getName(), ' # Points = ', geo.getNumberPoints() print 'Points = ', geo.getValuesString() geo.release() # for each Attribute, print Light Data and Values for i in range(grid.getNumberAttributes()) : attr = grid.getAttribute(i) print 'Attribute ', i, ' Name = ', attr.getName() # Attribute HeavyData is not Updated by default # there could potentially be many causing huge IO attr.read() print 'Values ', attr.getValuesString() attr.release() fe43c311473f7bee74fb6e8a351f580c3b0234fe Write Xdmf 0 9 111 61 2014-08-19T19:14:05Z Dave.demarle 5 wikitext text/x-wiki == Writing Xdmf == <pre style="color: red">Note this code snippet is from version 2 or 1 and needs updating for xdmf3.</pre> Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetShapeFromString("10 20 30") p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is built, the XML is blindly copied in and the writing of HeavyData is skipped. #!/usr/bin/env python from Xdmf import * # Example of How to Generate Xdmf # The Heavy Data for the Attribute is written separately # Write H5 Data arr = XdmfArray() arr.SetNumberType(XDMF_FLOAT64_TYPE) arr.SetShapeFromString("10 20 30") arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1) h5 = XdmfHDF() h5.CopyType(arr) h5.CopyShape(arr) h5.Open('XdmfByHand.h5:/Mydata', 'w') h5.Write(arr) h5.Close() # Use XdmfValuesHDF to generate the appropriate # Xdmf XML from and existing HDF5 dataset dv = XdmfValuesHDF() DataXml = dv.DataItemFromHDF('XdmfByHand.h5:/Mydata') # # Now build the tree of objects d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); # Insert the raw XML attr.SetDataXml(DataXml) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file This results in identical XML with just the name of the HDF5 dataset changed. ~ 802535eb3b5811d18d67dacaf4a65dc56e36df5a 114 111 2014-08-19T19:15:51Z Dave.demarle 5 /* Writing Xdmf */ wikitext text/x-wiki == Writing Xdmf == <pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre> Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetShapeFromString("10 20 30") p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file Would result in the Light Data XML to be written to the file Smesh.xmf and the Heavy data to be written to Xdmf.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">Xdmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfElements have a SetDataXml() method which takes a raw XML string. When the element is built, the XML is blindly copied in and the writing of HeavyData is skipped. #!/usr/bin/env python from Xdmf import * # Example of How to Generate Xdmf # The Heavy Data for the Attribute is written separately # Write H5 Data arr = XdmfArray() arr.SetNumberType(XDMF_FLOAT64_TYPE) arr.SetShapeFromString("10 20 30") arr.Generate(0.0, 1.0, 0, arr.GetNumberOfElements() - 1) h5 = XdmfHDF() h5.CopyType(arr) h5.CopyShape(arr) h5.Open('XdmfByHand.h5:/Mydata', 'w') h5.Write(arr) h5.Close() # Use XdmfValuesHDF to generate the appropriate # Xdmf XML from and existing HDF5 dataset dv = XdmfValuesHDF() DataXml = dv.DataItemFromHDF('XdmfByHand.h5:/Mydata') # # Now build the tree of objects d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("SampleLocation") i.SetValue("4") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); # Insert the raw XML attr.SetDataXml(DataXml) g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('SMesh.xmf') # write to file This results in identical XML with just the name of the HDF5 dataset changed. ~ f26ab0d7d54a0567bc85615a11bc4061f94e5acb 147 114 2014-11-10T17:16:38Z Burns 17 wikitext text/x-wiki == Writing Xdmf == Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Suppose we wanted to generate an XDMF dataset of a co-rectilinear mesh with scalar values at each node from Xdmf import * root = XdmfDomain.New() # Information info = XdmfInformation.New() # Arbitrary Name=Value Facility info.SetName("SampleLocation") info.SetValue("4") root.insert(i) # XML Domain is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Origin X,Y,Z newGridOrigin = XdmfArray.New() newGridOrigin.pushBackAsFloat64(1.0) newGridOrigin.pushBackAsFloat64(2.0) newGridOrigin.pushBackAsFloat64(3.0) # Offset X,Y,Z newBrickSize = XdmfArray.New() newBrickSize.pushBackAsFloat64(0.1) newBrickSize.pushBackAsFloat64(0.2) newBrickSize.pushBackAsFloat64(0.3) # Points per Dimensio0n newNumPoints = XdmfArray.New() newNumPoints.pushBackAsUInt32(10) newNumPoints.pushBackAsUInt32(20) newNumPoints.pushBackAsUInt32(30) # Grid grid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin) # Topology and Geometry are set based on the provided arrays grid.setName("Structured Grid") # Attribute attr = XdmfAttribute.New() attr.setName("Pressure") attr.setAttributeCenter(XdmfAttributeCenter.Node()); attr.setAttributeType(XdmfAttributeType.Scalar()); # The attribute has the same dims as the Grid attr.initialize(XdmfArrayType.Float64(), newNumPoints) # Fill with values however you prefer # Simply using a loop to fill in this case for i in range(0, 10 * 20 * 30) attr.insertAsFloat64(i, 5.0) grid.insert(attr) writer = XdmfWriter.New('SMesh.xmf') root.accept(writer) Would result in the Light Data XML to be written to the file SMesh.xmf and the Heavy data to be written to SMesh.h5. <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Information Name="SampleLocation" Value="4"/> <Domain> <Grid Name="Structured Grid" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" NumberOfElements="10 20 30 "/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 1 2 3 </DataItem> <DataItem Dimensions="3 " NumberType="Float" Precision="4" Format="XML"> 0.1 0.2 0.3 </DataItem> </Geometry> <Attribute Name="Pressure" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="6000 " NumberType="Float" Precision="4" Format="HDF">SMesh.xmf.h5:/Data</DataItem> </Attribute> </Grid> </Domain> </Xdmf> Now suppose the HDF5 already existed or we wanted to write the HDF5 files in a specific manner. All XdmfArrays can be provided a child HeavyDataController that points to a dataset in heavy data. When the XdmfWriter is set to DistributedHeavyData mode it will not read in the data and write it out to a new heavy data location. #!/usr/bin/env python from Xdmf import * # Example of How to Generate Xdmf # The Heavy Data for the Attribute is written separately # Write H5 Data array = XdmfArray.New() dims = UInt32Vector() dims.push_back(10) dims.push_back(20) dims.push_back(30) array.initialize(XdmfArrayType.Float64(), dims) # Simply using a loop to fill in this case for i in range(0, 10 * 20 * 30) attr.insertAsFloat64(i, 5.0) h5writer = XdmfHDF5Writer.New('XdmfByHand.h5') array.accept(h5writer) # Retrieve the data set that the writer wrote to dataset = array.getHeavyDataController().getDataSetPath() root = XdmfDomain.New() root.SetDOM(d) # Information i = XdmfInformation.New() # Arbitrary Name=Value Facility i.setName("SampleLocation") i.setValue("4") root.insert(i) # XML Domain is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Origin X,Y,Z newGridOrigin = XdmfArray.New() newGridOrigin.pushBackAsFloat64(1.0) newGridOrigin.pushBackAsFloat64(2.0) newGridOrigin.pushBackAsFloat64(3.0) # Offset X,Y,Z newBrickSize = XdmfArray.New() newBrickSize.pushBackAsFloat64(0.1) newBrickSize.pushBackAsFloat64(0.2) newBrickSize.pushBackAsFloat64(0.3) # Points per Dimensio0n newNumPoints = XdmfArray.New() newNumPoints.pushBackAsUInt32(10) newNumPoints.pushBackAsUInt32(20) newNumPoints.pushBackAsUInt32(30) # Grid grid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin) # Topology and Geometry are set based on the provided arrays grid.setName("Structured Grid") root.insert(g) # Attribute attr = XdmfAttribute.New() attr.setName("Pressure") attr.setAttributeCenter(XdmfAttributeCenter.Node()) attr.setAttributeType(XdmfAttributeType.Scalar()) # Build a heavy data controller starts = UInt32Vector() starts.push_back(0) starts.push_back(0) starts.push_back(0) strides = UInt32Vector() strides.push_back(1) strides.push_back(1) strides.push_back(1) controller = XdmfHDF5Controller.New('SMesh.h5', dataset, # Stored from earlier XdmfArrayType.Float64(), starts, strides, dims, dims) writer = XdmfWriter.New('secondSMesh.h5') writer.setMode(XdmfWriter.DistributedHeavyData) root.accept(writer) This results in identical XML with just the name of the HDF5 dataset changed. 26ecfd7412cf299d9152061ee7642130d1e17b70 XDMF API 0 3 112 55 2014-08-19T19:14:41Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <pre style="color: red">Note this code snippet is from version 2 or 1 and needs updating for xdmf3.</pre> '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parse strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement ( XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1 ) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfTime''' When UpdateInformation() gets called for a Grid, an XdmfTime object is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there is a &lt;Time&gt; element in the Grid the object is populated. If the Grid is Non-Uniform (i.e. Collection, Tree), the children are updated as well. If the parent is TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the appropriate value set. Methods : XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0) This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten. XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax) this checks to see if the Time is entirely in Min/Max. Since this is a float comparison, I added an Epsilon member to XdmfTime with default value = 1e-7. This may be changed via XdmfTime::SetEpsilon() XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill) This populates the array with the direct children that are entirely in min/max. For example if the range is 0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL. '''XdmfHDF''' In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) # If an array is given a HeavyDataSetName, that is # where it will be written p.setHeavyDataSetName('MyData.h5:/Pressure') g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file 6897f36e2ed3f4367016ac487db88edc7f2f3ee9 113 112 2014-08-19T19:15:13Z Dave.demarle 5 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre> '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parse strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement ( XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1 ) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfTime''' When UpdateInformation() gets called for a Grid, an XdmfTime object is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there is a &lt;Time&gt; element in the Grid the object is populated. If the Grid is Non-Uniform (i.e. Collection, Tree), the children are updated as well. If the parent is TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the appropriate value set. Methods : XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0) This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten. XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax) this checks to see if the Time is entirely in Min/Max. Since this is a float comparison, I added an Epsilon member to XdmfTime with default value = 1e-7. This may be changed via XdmfTime::SetEpsilon() XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill) This populates the array with the direct children that are entirely in min/max. For example if the range is 0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL. '''XdmfHDF''' In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) # If an array is given a HeavyDataSetName, that is # where it will be written p.setHeavyDataSetName('MyData.h5:/Pressure') g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file df2f69e2404d3bbe9a8bac1f8567ca0e537a8a2e 127 113 2014-11-07T15:36:29Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre> '''XDMF API''' [[Xdmf2 API Archive]] While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parse strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement ( XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1 ) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfTime''' When UpdateInformation() gets called for a Grid, an XdmfTime object is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there is a &lt;Time&gt; element in the Grid the object is populated. If the Grid is Non-Uniform (i.e. Collection, Tree), the children are updated as well. If the parent is TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the appropriate value set. Methods : XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0) This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten. XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax) this checks to see if the Time is entirely in Min/Max. Since this is a float comparison, I added an Epsilon member to XdmfTime with default value = 1e-7. This may be changed via XdmfTime::SetEpsilon() XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill) This populates the array with the direct children that are entirely in min/max. For example if the range is 0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL. '''XdmfHDF''' In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) # If an array is given a HeavyDataSetName, that is # where it will be written p.setHeavyDataSetName('MyData.h5:/Pressure') g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file dbbc9a7368ea729c67f58d6e578db3b000ee1dee 130 127 2014-11-07T15:43:23Z Burns 17 Replaced content with "[[Image:XdmfLogo1.gif]] '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that ma..." wikitext text/x-wiki [[Image:XdmfLogo1.gif]] '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. [[Xdmf3 C++ API]] [[Xdmf3 Python API]] [[Xdmf3 Fortran API]] [[Xdmf2 API Archive]] 3b345f2f6f95331759133b19b8788859fd0c5bdd Write from Fortran 0 10 115 51 2014-08-19T19:16:41Z Dave.demarle 5 /* Writing Xdmf from Fortran */ wikitext text/x-wiki == Writing Xdmf from Fortran == <pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre> Xdmf can be generated in many different manners. Using the low level HDF5 library and print statements is certainly one of them. Utilizing the XDMF API, however, provides some convenient advantages. Consider the following Fortran program which build a grid of Hexahedra with some node and cell centered values : CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Grid of Hexahedron Centered at 0,0,0 C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CreateGrid( IDIM, JDIM, KDIM, XYZ, ICONN ) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) INTEGER I, J, K, IDX REAL*8 X, Y, Z, DX, DY, DZ C Print *, 'Size = ', IDIM, JDIM, KDIM PRINT *, 'Initialze Problem' C XYZ Values of Nodes C From -1 to 1 DX = 2.0 / ( IDIM - 1 ) DY = 2.0 / ( JDIM - 1 ) DZ = 2.0 / ( KDIM - 1 ) Z = -1.0 DO 112 K= 1, KDIM Y = -1.0 DO 111 J= 1, JDIM X = -1.0 DO 110 I= 1, IDIM XYZ( 1, I, J, K ) = X XYZ( 2, I, J, K ) = Y XYZ( 3, I, J, K ) = Z X = X + DX 110 CONTINUE Y = Y + DY 111 CONTINUE Z = Z + DZ 112 CONTINUE C Connections IDX = 1 DO 122 K= 0, KDIM - 2 DO 121 J= 0, JDIM - 2 DO 120 I= 1, IDIM - 1 ICONN( 1, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 2, IDX ) = ( K * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 3, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I + 1 ICONN( 4, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + ( J * IDIM ) + I ICONN( 5, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I ICONN( 6, IDX ) = ( K * JDIM * IDIM ) + ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 7, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I + 1 ICONN( 8, IDX ) = ( ( K + 1 ) * JDIM * IDIM ) + C ( ( J + 1 ) * IDIM ) + I IDX = IDX + 1 120 CONTINUE 121 CONTINUE 122 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Node Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) INTEGER IDIM, JDIM, KDIM REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) INTEGER I, J, K REAL*8 X, Y, Z PRINT *, 'Calculating Node Centered Data' DO 212, K=1, KDIM DO 211, J=1, JDIM DO 210, I=1, IDIM X = XYZ( 1, I, J, K ) Y = XYZ( 2, I, J, K ) Z = XYZ( 3, I, J, K ) NCVALUES( I, J, K ) = SQRT( ( X * X ) + ( Y * Y ) + ( Z * Z )) 210 CONTINUE 211 CONTINUE 212 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Create a Cell Centered Solution Field C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC SUBROUTINE CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) INTEGER IDIM, JDIM, KDIM, ITER, KICKER REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) INTEGER I, J, K PRINT *, 'Calculating Cell Centered Data for Iteration ', ITER DO 312, K=1, KDIM - 1 DO 311, J=1, JDIM - 1 DO 310, I=1, IDIM - 1 X = XYZ( 1, I, J, K ) CCVALUES( I, J, K ) = C SIN( ( ( X + 1 ) * IDIM * KICKER ) / 3 * ITER ) / C EXP( X / ( 1.0 * ITER ) ) 310 CONTINUE 311 CONTINUE 312 CONTINUE C Waste Time DO 313 I=1, 1000000 X = 0.1 * ITER / I Y = SQRT( X * X ) Z = EXP( Y ) 313 CONTINUE RETURN END CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC C C Main Program : C Initialize Grid C Initialize Node Centered Data C For Iteration = 1 to 10 C Generate Cell Centered Data C Done C CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC PROGRAM HexMesh PARAMETER ( IDIM = 11 ) PARAMETER ( JDIM = 13 ) PARAMETER ( KDIM = 15 ) REAL*8 XYZ DIMENSION XYZ( 3, IDIM, JDIM, KDIM ) REAL*8 NCVALUES DIMENSION NCVALUES( IDIM, JDIM, KDIM ) C REAL*8 CCVALUES DIMENSION CCVALUES( IDIM - 1, JDIM - 1, KDIM - 1 ) C INTEGER ICONN DIMENSION ICONN ( 8, ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 )) C INTEGER ITER, KICKER, NITER, NARG INTEGER IUNIT CHARACTER*80 ARGIN C NARG = IARGC() IF( NARG .GE. 1 ) THEN CALL GETARG( 1, ARGIN ) READ( ARGIN, '(I)') NITER ELSE NITER = 10 ENDIF CALL CreateGrid ( IDIM, JDIM, KDIM, XYZ, ICONN ) CALL NodeData( IDIM, JDIM, KDIM, XYZ, NCVALUES) C IUNIT = 14 OPEN( IUNIT, FILE='XYZ.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) IDIM * JDIM * KDIM WRITE ( IUNIT, * ) XYZ CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CONN.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) 'Hex', ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) WRITE ( IUNIT, * ) ICONN CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='NodeValues.dat', STATUS='unknown' ) REWIND IUNIT WRITE ( IUNIT, * ) NCVALUES CLOSE ( IUNIT ) C IUNIT = 14 OPEN( IUNIT, FILE='CellValues.dat', STATUS='unknown' ) REWIND IUNIT C KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Running the program produces four files XYZ.dat, CONN.dat, NodeValues.dat and CellValues.dat. Now let's suppose we want to generate Xdmf. We could use the HDF5 fortran bindings and produce the XML via print statements (we could also shove bamboo shoots under our fingernails). A better approach would be to create a 'C' wrapper routine that we call from fortran which contains all of the necessary Xdmf calls to produce valid Xdmf XML and HDF5 files : #include <Xdmf.h> // We want the filenames to be based on the iteration // and padded with zeros using std::setw; using std::setfill; // This works with g77. Different compilers require different // name mangling. '''#define XdmfWrite xdmfwrite_''' // // C/C++ expect NULL terminated strings. Here is a conversion subroutine. char * DemoConvertFortranString( char *FtnName ) { static char Name[80]; char *np; memcpy(Name, FtnName, 79 ); Name[79] = '\0'; np = &Name[78]; while( ( np > Name ) && ( *np <= ' ') ) { np--; } *np = '\0'; return( Name ); } // // C++ will mangle the name based on the argument list. This tells the // compiler not to mangle the name so we can call it from 'C' (but // really Fortran in this case) // extern "C" { // void '''XdmfWrite(''' char *FtnName, int *Iteration, int *NumberOfPoints, int *NumberOfHex, XdmfFloat64 *Points, XdmfInt32 *Conns, XdmfFloat64 *NodeData, XdmfFloat64 *CellData){ char *Name; char FullName[80]; ostrstream DataName(FullName, 80); XdmfDOM dom; XdmfRoot root; XdmfDomain domain; XdmfGrid grid; XdmfTime time; XdmfTopology *topology; XdmfGeometry *geometry; XdmfAttribute nodedata; XdmfAttribute celldata; XdmfArray *array; Name = DemoConvertFortranString( FtnName ); root.SetDOM(&dom); root.SetVersion(2.0); root.Build(); // Domain root.Insert(&domain); // Grid grid.SetName("Demonstration Grid"); domain.Insert(&grid); time.SetTimeType(XDMF_TIME_SINGLE); time.SetValue(0.001 * *Iteration); grid.Insert(&time); // Topology topology = grid.GetTopology(); topology->SetTopologyType(XDMF_HEX); topology->SetNumberOfElements(*NumberOfHex); // Fortran is 1 based while c++ is 0 based so // Either subtract 1 from all connections or specify a BaseOffset topology->SetBaseOffset(1); // If you haven't assigned an XdmfArray, GetConnectivity() will create one. array = topology->GetConnectivity(); array->SetNumberOfElements(*NumberOfHex * 8); array->SetValues(0, Conns, *NumberOfHex * 8); // C++ string hocus pocus. // We're actually building the string in FullName[] but were using streams. // the DatasetName will be Demo_00001.h5:/Conns. DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Conns" << ends; // Where the data will actually be written array->SetHeavyDataSetName(FullName); // Geometry geometry = grid.GetGeometry(); geometry->SetGeometryType(XDMF_GEOMETRY_XYZ); geometry->SetNumberOfPoints(*NumberOfPoints); array = geometry->GetPoints(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetValues(0, Points, *NumberOfPoints * 3); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/Points" << ends; array->SetHeavyDataSetName(FullName); // Node Data nodedata.SetName("Node Scalar"); nodedata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_NODE); nodedata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = nodedata.GetValues(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetNumberOfElements(*NumberOfPoints); array->SetValues(0, NodeData, *NumberOfPoints); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/NodeData" << ends; array->SetHeavyDataSetName(FullName); // Cell Data celldata.SetName("Cell Scalar"); celldata.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); celldata.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); array = celldata.GetValues(); array->SetNumberType(XDMF_FLOAT64_TYPE); array->SetNumberOfElements(*NumberOfHex); array->SetValues(0, CellData, *NumberOfHex); DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".h5:/CellData" << ends; array->SetHeavyDataSetName(FullName); // Attach and Write grid.Insert(&nodedata); grid.Insert(&celldata); // Build is recursive ... it will be called on all of the child nodes. // This updates the DOM and writes the HDF5 root.Build(); // Write the XML DataName.seekp(0); DataName << Name << "_" << setw(5) << setfill('0') << *Iteration << ".xmf" << ends; dom.Write(FullName); } } Now we modify the Original Fortran code to call our new 'C' wrapper subroutine '''XdmfWrite()''' Original : KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES 1000 CONTINUE CLOSE ( IUNIT ) C END Modified : INHEX = ( IDIM - 1 ) * ( JDIM - 1 ) * ( KDIM - 1 ) INPNT = IDIM * JDIM * KDIM KICKER = NITER DO 1000 ITER = 1, NITER CALL CellData( IDIM, JDIM, KDIM, ITER, KICKER, XYZ, CCVALUES) WRITE ( IUNIT, * ) CCVALUES '''CALL XDMFWRITE( 'Demo', ITER, INPNT, INHEX, XYZ, ICONN, NCVALUES, CCVALUES)''' 1000 CONTINUE CLOSE ( IUNIT ) C END The program now produces one HDF5 file and one XML file for each iteration. Here is one of the XML output files : <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2"> <Domain> <Grid Name="Demonstration Grid" GridType="Uniform"> <Topology TopologyType="Hexahedron" NumberOfElements="1680 " BaseOffset="1"> <DataItem Dimensions="13440 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Conns</DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Dimensions="6435 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/Points</DataItem> </Geometry> <Time TimeType="Single" Value="0.004"/> <Attribute Name="Node Scalar" AttributeType="Scalar" Center="Node"> <DataItem Dimensions="2145 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/NodeData</DataItem> </Attribute> <Attribute Name="Cell Scalar" AttributeType="Scalar" Center="Cell"> <DataItem Dimensions="1680 " NumberType="Float" Precision="4" Format="HDF">Demo_00004.h5:/CellData</DataItem> </Attribute> </Grid> </Domain> </Xdmf> The final step would be to group all of these together so we could animate them over time. Instead of duplicating the XML in another file for each grid, we can use a little XML magic to pull them together : <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2001/XInclude" Version="2.0"> <Domain> <Grid GridType="Collection" CollectionType="Temporal"> <xi:include href="Demo_00001.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00002.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00003.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00004.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00005.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00006.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00007.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00008.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00009.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> <xi:include href="Demo_00010.xmf" xpointer="xpointer(//Xdmf/Domain/Grid)" /> </Grid> </Domain> </Xdmf> This uses XInclude and XPointer terminology to create a '''Temporal Collection''' Grid that consists of the first (in our case, the only) grid in each file. This XML file could be generated programmtically or by a post processing script. e32bc46bdc3a44a15f4cdf5e71e5886f92e84806 Read from MySQL 0 11 116 54 2014-08-19T19:17:14Z Dave.demarle 5 /* Accessing a MySQL DataBase */ wikitext text/x-wiki == '''Accessing a MySQL DataBase''' == <pre style="color: red">Note SQL support was removed in xdmf 3.</pre> Partial support for reading data from a MySQL database is available. MySQL is treated as another HeavyData format like HDF5. Currently database access is ReadOnly and is accessed by setting the '''Format''' of the '''DataItem''' in XML equal to '''MySQL''' <Attribute Name="Cell Centered Values" Center="Cell"> <DataItem Format="MySQL" Server="localhost" User="root" DataBase="MnmiFromout" Dimensions="3" NumberType="Float"> <![CDATA[SELECT X FROM Locations WHERE Time < 0.21]]> </DataItem> </Attribute> A Valid SQL statement is placed in the CDATA of the DataItem. When the XdmfDataItem is updated, an atomic query is made and the result is placed in the XdmfArray of the DataItem. Putting a "<" (less than) in the CDATA will cause an error in the XML parser. The XML example above shows how to do this correctly. The Server, User, and DataBase attributes tell Xdmf how to access MySQL. There is also a Password attribute. Currently this is just clear text which is a really bad idea. This will change. ce1e7dcb75dd0037a9db8695950dacfaf286f53b Parallel IO with MPI 0 12 117 69 2014-08-19T19:17:41Z Dave.demarle 5 wikitext text/x-wiki <pre style="color: red">Note code snippets on this page are from version 2 or 1 and need updating for xdmf 3.</pre> (code, example and description provided by Will Dicharry) === Controlling the I/O process for XdmfHeavyData === The XDMF API provides a customization point to allow the heavy data sets to be written in a certain manner, depending on the application environment and independent of the heavy dataset format. New I/O strategies can be implemented by subclassing the callback classes defined in XdmfHeavyData.h and attaching them to XdmfHeavyData classes. This method has the advantage of applying a common strategy to any XdmfHeavyData subclass. The system works in the following way: XdmfHeavyData contains the non-virtual methods Open, Close, Read, and Write and the virtual methods DoOpen, DoClose, DoRead, and DoWrite. XdmfHeavyData subclasses should override these to open, close, read, and write a particular heavy data format independent of the application environment. In addition there are 4 callback base classes XdmfOpenCallback, XdmfCloseCallback, XdmfReadCallback, and XdmfWriteCallback. The callbacks should be implemented to replace the XdmfHeavyData's own Do methods. To decorate the existing I/O code, call dataset->Do* within the callback's Do* method. This allows implementors to define both pre and post callbacks, or even disable the output of a dataset entirely. === Example === Suppose we have an MPI environment with 4 processes. Each process contains part of an array with 100 values numbered 0 to 99; process 0 with items 0-24, process 1 with items 25-49, etc. We would like to write this data to a single HDF file containing a single array of 100 values, stored in increasing numerical order. To do this, we will communicate all of the data to process 0 and let process 0 handle the actual output of the array. We start by including the necessary headers and defining a very simple stream buffer utility class that simplifies encoding and decoding data between processes: <code> #include <mpi.h> #include <XdmfArray.h> #include <XdmfHDF.h> /// Simple memory buffer implementation that keeps track of it's stream pointer. class Buffer { private: std::size_t m_size; char* m_data; char* m_put; char* m_tell; public: Buffer( std::size_t size ) : m_size( size ), m_data( new char[size] ), m_put( m_data ), m_tell( m_data ) {} ~Buffer() { delete [] m_data; } /// copy a contiguous block into the buffer void put( const void* data, std::size_t size ) { memcpy( m_put, data, size ); m_put += size; } /// put a single value into the buffer template< typename T > void put( const T& t ) { std::size_t size = sizeof( T ); put( &t, size ); } /// copy a contiguous block of data from the buffer to an already /// allocated location void tell( void* out, std::size_t size ) { memcpy( out, m_tell, size ); m_tell += size; } /// Copy a single value into the buffer. template< typename T > T tell() { std::size_t tsize = sizeof( T ); T tmp; tell( &tmp, tsize ); return tmp; } std::size_t size() const { return m_size; } char* pointer() { return m_data; } void reset() { m_put = m_data; m_tell = m_data; } }; </code> We haven't yet called on the Xdmf API to do anything, the Buffer class is just a utility that we will use later. Now, we write our callback class that will customize the process of opening, reading, writing, and closing the heavy dataset. Since our communication strategy must implement a new function for each step, we will write one class that inherits XdmfOpenCallback, XdmfCloseCallback, XdmfWriteCallback, and XdmfReadCallback. Each one of the base classes has a single virtual method that takes a pointer to a XdmfHeavyData and the same arguments that XdmfHeavyData::Open, XdmfHeavyData::Close, XdmfHeavyData::Write, or XdmfHeavyData::Write would take and wraps the synchronization code around the actual XdmfHeavyData methods. Note that we call the virtual DoOpen, DoClose, DoRead, and DoWrite methods rather than the non-virtual Open, Close, Read, and Write methods. <code> /// Callback implements parallel IO by communicating to process 0 class CommunicationCallback : public XdmfOpenCallback, public XdmfWriteCallback, public XdmfCloseCallback, public XdmfReadCallback { private: int mCommRank; int mCommSize; public: /// Constructor initializes the Number of processors and local process /// ID. CommunicationCallback() { MPI_Comm_size( MPI_COMM_WORLD, &mCommSize ); MPI_Comm_rank( MPI_COMM_WORLD, &mCommRank ); } /// Reimplemented from XdmfOpenCallback::DoOpen. Only rank 0 is going /// to read or write, so only rank 0 will open the file. XdmfInt32 DoOpen( XdmfHeavyData* ds, XdmfConstString name, XdmfConstString access ) { if ( mCommRank == 0 ) { // Call the actual DoOpen method from XdmfHeavyData return ds->DoOpen( name, access ); } else { // Not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfCloseCallback::DoClose. Again, only rank 0 /// needs to do anything. XdmfInt32 DoClose( XdmfHeavyData* ds ) { if ( mCommRank == 0 ) { // Call the heavy dataset's native close method. return ds->DoClose(); } else { // not rank 0, nothing to do. return XDMF_SUCCESS; } } /// Reimplemented from XdmfWriteCallback::DoWrite. If the local /// process ID is 0, then we expect to receive data from everyone /// else. Otherwise, we send data. Rank 0 does all of the writing. XdmfInt32 DoWrite( XdmfHeavyData* ds, XdmfArray* array ) { // This implementation assumes process 0 has the same data // size as everyone else // set up a stream buffer that is large enough to hold the data to // be sent or received. We require enough space for the rank, // start, stride, and count for the array plus enough space to hold // the actual array data. XdmfInt64 start[1], stride[1], count[1]; XdmfInt32 slab_rank = ds->GetHyperSlab( start, stride, count ); std::size_t slab_info_size = sizeof( XdmfInt32 ) // slab rank + slab_rank * sizeof( XdmfInt64 ) * 3; // start, stride, and count Buffer buf( slab_info_size + array->GetCoreLength() ); // If the local process ID is nonzero, pack the buffer and send to // process 0. if ( mCommRank != 0 ) { // copy rank and slab information into the buffer. buf.put( slab_rank ); for ( int i = 0; i < slab_rank; ++i ) { buf.put( start[i] ); buf.put( stride[i] ); buf.put( count[i] ); } // copy the actual data into the buffer. buf.put( array->GetDataPointer(), array->GetCoreLength() ); // send to rank 0 in the global communicator. MPI_Send( buf.pointer(), buf.size(), MPI_BYTE, 0, 0, MPI_COMM_WORLD ); } else { // Local process ID is 0, so we write local data then receive and // write remote data. // first, it's easy to write the local data ds->DoWrite( array ); int processes_received = 1; // local data for process 0 is written // loop until the data for all processes has been received. while ( processes_received < mCommSize ) { // Fill the buffer with incoming data. We are assuming here // that all processes contain the same amount of data. MPI_Recv( buf.pointer(), buf.size(), MPI_BYTE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, 0 ); processes_received++; // unpack the buffer buf.reset(); // reset the stream pointer to the beginning // we mean rank in the linear algebra sense here slab_rank = buf.tell< XdmfInt32 >(); // start, stride, and count are next. for( int i = 0; i < slab_rank; ++i ) { start[i] = buf.tell< XdmfInt64 >(); stride[i] = buf.tell< XdmfInt64 >(); count[i] = buf.tell< XdmfInt64 >(); } // select the correct hyper slab in the heavy data set. ds->SelectHyperSlab( start, stride, count ); // allocate an array to hold the off-core data. XdmfArray* recv = new XdmfArray; recv->CopyShape( array ); // place the received data into the array. buf.tell( recv->GetDataPointer(), recv->GetCoreLength() ); // write the off core data to the dataset by calling the heavy // data's DoWrite method. ds->DoWrite( recv ); delete recv; } } return XDMF_SUCCESS; } /// Reimplemented from XdmfReadCallback::DoRead. Read the data from a /// heavy data source into an array only if the local process ID is 0. /// Otherwise, do nothing. XdmfArray* DoRead( XdmfHeavyData* ds, XdmfArray* array ) { if ( mCommRank == 0 ) { // defer to the actual heavy data implementation of DoRead. return ds->DoRead( array ); } else { // return an empty array. return NULL; } } }; // end of class CommunicationCallback </code> One of the useful features of the above code is that it relies only on the abstract portion of the XdmfHeavyData interface. Therefore, it is general enough to be used when writing to any heavy dataset (either HDF or MySQL). In the future, if other heavy data output formats are added, the same strategy could apply to them as well. Now, we write a main program that generates the data, writes to an HDF dataset, and reads from the same file to verify the round trip. <code> char const * const kDatasetName = "FILE:TestFile.h5:/XdmfHDFMPI"; int main( int argc, char* argv[] ) { // Initialize MPI MPI_Init( &argc, &argv ); // determine the local process ID int rank; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); // Create an HDF dataset to write out to. XdmfHDF* H5 = new XdmfHDF(); // Attach an instance of the CommunicationCallback class defined above // to customize opening, writing, and closing the dataset. CommunicationCallback* cb = new CommunicationCallback; H5->setOpenCallback( cb ); H5->setWriteCallback( cb ); H5->setCloseCallback(cb ); // Allocate an array of size 25 and fill it with values depending // on the local process ID (process 0 has 0-24, process 1 has // 25-49,...) XdmfArray* MyData = new XdmfArray(); MyData->SetNumberType( XDMF_FLOAT32_TYPE ); MyData->SetNumberOfElements( 25 ); MyData->Generate( rank * 25, rank*25 + 24 ); // Set the dataset's type to the array's type H5->CopyType( MyData ); // Set up the dimensions of the dataset. XdmfInt64 dims[1]; dims[0] = 100; H5->SetShape( 1, dims ); // Set up the hyper slab for the dataset. Each process will select a // distinct portion of the dataset (process 0 has 0-24, process 1 // 25-49,...) XdmfInt64 start[1], stride[1], count[1]; start[0] = rank * 25; stride[0] = 1; count[0] = 25; // select the slab in the dataset corresponding to the local process. H5->SelectHyperSlab( start, stride, count ); // Open the dataset. H5->Open( kDatasetName, "w" ); // Write the array. H5->Write( MyData ); // Close the dataset. H5->Close(); // writing is complete, now we have a quick test to ensure the data // survives a round trip. bool failure = false; // Create a new dataset to read from XdmfHDF* H5In = new XdmfHDF(); // Use the same callback. H5In->setReadCallback( cb ); H5In->setOpenCallback( cb ); H5In->setCloseCallback( cb ); // Open the dataset for reading. H5In->Open( kDatasetName, "r" ); // Read the data into an array. XdmfArray* result = H5In->Read(); // if the read was successful, make sure the values for all processes // are in the file. if ( result ) { for ( size_t i = 0; i < 100; ++i ) { float value = result->GetValueAsFloat32( i ); std::cout << i << " " << value << std::endl; failure = ( value != i ); } } MPI_Finalize(); delete H5; delete cb; delete MyData; delete H5In; delete result; if ( failure ) { return -1; } else { return 0; } }; </code> Running the program in an MPI environment with 4 processes produces a single HDF5 file TestFile.h5 with a single dataset XdmfHDFMPI containing the numbers 0 to 99. The full source of this example is available in the Xdmf source tree. 2b22f6ea7c357c6b6dd0540713c9518e01f549e6 148 117 2014-11-10T19:48:18Z Burns 17 wikitext text/x-wiki <pre style="color: red">Note: as of version 1.8.13 hdf5 must be patched as follows to allow for this functionality.</pre> In the file /hdf5/src/CMakeLists.txt change if (NOT HDF5_INSTALL_NO_DEVELOPMENT) install ( FILES ${H5_PUBLIC_HEADERS} DESTINATION ${HDF5_INSTALL_INCLUDE_DIR} COMPONENT headers ) endif (NOT HDF5_INSTALL_NO_DEVELOPMENT) to if (NOT HDF5_INSTALL_NO_DEVELOPMENT) install ( FILES ${H5_PUBLIC_HEADERS} ${H5_PRIVATE_HEADERS} DESTINATION ${HDF5_INSTALL_INCLUDE_DIR} COMPONENT headers ) endif (NOT HDF5_INSTALL_NO_DEVELOPMENT) ===Distributed Shared Memory=== By leveraging the h5fd and hdf5 libraries, Xdmf provides an interface by which a user can set up a dsm server that may be interacted with in a manner similar to hdf5. As of Xdmf 3.0.0, DSM only allows for the existance of one dataset at a time. This may be worked around by defining a superset and writing datasets to subsections of that superset. ====Initializing DSM==== After starting MPI, the DSM can be started by creating an instance of XdmfHDF5WriterDSM or XdmfHDF5ControllerDSM. int size, id, dsmSize; dsmSize = 64;//The total size of the DSM being created std::string newPath = "dsm"; unsigned int numServersCores = 2; MPI_Comm comm = MPI_COMM_WORLD; MPI_Init(&argc, &argv); MPI_Comm_rank(comm, &id); MPI_Comm_size(comm, &size); unsigned int dataspaceAllocated = dsmSize/numServersCores; // Splitting MPICommWorld so that a comm that contains the non-Server cores exists. MPI_Comm workerComm; MPI_Group workers, dsmgroup; MPI_Comm_group(comm, &dsmgroup); int * ServerIds = (int *)calloc((numServersCores), sizeof(int)); unsigned int index = 0; for(int i=size-numServersCores ; i <= size-1 ; ++i) { ServerIds[index++] = i; } MPI_Group_excl(dsmgroup, index, ServerIds, &workers); int testval = MPI_Comm_create(comm, workers, &workerComm); cfree(ServerIds); // The last two cores in the Comm are regulated to manage the DSM. shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dataspaceAllocated, size-numServersCores, size-1); This creates a DSM buffer and manager which must be passed to any new DSM objects in order for those objects to function. After the user is finished with DSM the manager must be disposed of. Not doing this will result in an error. if (id == 0) { exampleWriter->stopDSM(); } MPI_Barrier(comm); //the dsmManager must be deleted or else there will be a segfault exampleWriter->deleteManager(); MPI_Finalize(); A full example program can be found in the Xdmf source at: Xdmf/core/dsm/tests/Cxx/DSMLoopTest.cpp c063b01c1ec82d9cbc27f3c2e894fbc75805b07a 149 148 2014-11-10T19:48:48Z Burns 17 wikitext text/x-wiki <pre style="color: red">Note: as of version 1.8.13 hdf5 must be patched as follows to allow for this functionality.</pre> In the file /hdf5/src/CMakeLists.txt change if (NOT HDF5_INSTALL_NO_DEVELOPMENT) install ( FILES ${H5_PUBLIC_HEADERS} DESTINATION ${HDF5_INSTALL_INCLUDE_DIR} COMPONENT headers ) endif (NOT HDF5_INSTALL_NO_DEVELOPMENT) to if (NOT HDF5_INSTALL_NO_DEVELOPMENT) install ( FILES ${H5_PUBLIC_HEADERS} ${H5_PRIVATE_HEADERS} DESTINATION ${HDF5_INSTALL_INCLUDE_DIR} COMPONENT headers ) endif (NOT HDF5_INSTALL_NO_DEVELOPMENT) ===Distributed Shared Memory=== By leveraging the h5fd and hdf5 libraries, Xdmf provides an interface by which a user can set up a dsm server that may be interacted with in a manner similar to hdf5. As of Xdmf 3.0.0, DSM only allows for the existance of one dataset at a time. This may be worked around by defining a superset and writing datasets to subsections of that superset. ====Initializing DSM==== After starting MPI, the DSM can be started by creating an instance of XdmfHDF5WriterDSM or XdmfHDF5ControllerDSM. int size, id, dsmSize; dsmSize = 64;//The total size of the DSM being created std::string newPath = "dsm"; unsigned int numServersCores = 2; MPI_Comm comm = MPI_COMM_WORLD; MPI_Init(&argc, &argv); MPI_Comm_rank(comm, &id); MPI_Comm_size(comm, &size); unsigned int dataspaceAllocated = dsmSize/numServersCores; // Splitting MPICommWorld so that a comm that contains the non-Server cores exists. MPI_Comm workerComm; MPI_Group workers, dsmgroup; MPI_Comm_group(comm, &dsmgroup); int * ServerIds = (int *)calloc((numServersCores), sizeof(int)); unsigned int index = 0; for(int i=size-numServersCores ; i <= size-1 ; ++i) { ServerIds[index++] = i; } MPI_Group_excl(dsmgroup, index, ServerIds, &workers); int testval = MPI_Comm_create(comm, workers, &workerComm); cfree(ServerIds); // The last two cores in the Comm are regulated to manage the DSM. shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dataspaceAllocated, size-numServersCores, size-1); This creates a DSM buffer and manager which must be passed to any new DSM objects in order for those objects to function. After the user is finished with DSM the manager must be disposed of. Not doing this will result in an error. if (id == 0) { exampleWriter->stopDSM(); } MPI_Barrier(comm); //the dsmManager must be deleted or else there will be a segfault exampleWriter->deleteManager(); MPI_Finalize(); A full example program can be found in the Xdmf source at: Xdmf/core/dsm/tests/Cxx/DSMLoopTest.cpp b6a7f48b2a7a304e6c3bc9992a6a71d6aa63266f Get Xdmf original 0 6 118 35 2014-08-19T19:21:11Z Dave.demarle 5 /* Obtaining and Installing XDMF */ wikitext text/x-wiki == '''Obtaining and Installing XDMF''' == <pre style="color: red"> These instruction pertain to Xdmf version 1. </pre> The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, on the HPC systems at the ARL MSRC. If you need access on other platforms, obtain the source via CVS and follow the installation instructions. XDMF has been built and tested on a variety of UNIX platforms and on Win32 and Cygwin. CVS Access to the XDMF Source Code Repository XDMF is obtained via CVS access to the XDMF source code repository as a user (anonymous, read-only access). One of the advantages of CVS access is that you can incrementally update your repository without having to retrieve the entire source distribution. The following assumes that you have a basic knowledge of CVS. Anonymous User Read-Only Access You can obtain read-only access to the CVS repository as follows. cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login (respond with password xdmf) Follow this command by checking out the source code: cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf This CVS tree is Xdmf. Checkout the CVS in a clean directory as it will create an Xdmf directory and possibly overwrite an existing Xdmf tree. You will also need CMake which is a new cross platform build tool. '''Installation''' XDMF depends on Expat and HDF5. While a version of Expat and HDF5 comes with the the XDMF source, you might want to get the latest version of these packages. Obtain Expat from here . Obtain HDF from here. You'll also want Python (version 2.5 or later). Obtain Python from [http://www.python.org Python.Org]. If you want to use the scientific visualization tools, you'll need vtk ( version 5.0 or later ). Obtain vtk from [http://public.kitware.com Kitware.Com]. Xdmf uses CMake for installation. Pre-Built binaries of CMake are available for many platforms, or you can install from source. The advantage of CMake is that it provides a consistent build system for UNIX and Win32. For this reason, we replaced the previous autoconf <nowiki>(./configure --prefix...)</nowiki> method with CMake. Once you�ve installed the necessary support packages, begin to build Xdmf for your platform. For example, suppose you wish to build a Linux version : # mkdir MyXdmf # cd MyXdmf # cvs <nowiki>-d ...</nowiki> login # cvs <nowiki>-d ...</nowiki> co Xdmf This creates an Xdmf directory of the source code # mkdir Linux # cd Linux # cmake ../Xdmf CMake comes with several different commands. The two most important are cmake (the command line version) and ccmake (a curses based gui version). Both versions create a Makefile in the current directory and a file ''CMakeCache.txt'' that contains the compile time options. Options include things like additional compiler flags, where to find various packages (like HDF and expat), and which parts to build ( shared objects, python interface, etc.). As you change the CMakeCache.txt file either by hand or via the gui, additional options may appear. For example, if you decide to build the Python interface, new options for the location of Python include files and libraries will appear in the CMakeCache.txt file after you re-run cmake. In short, you run cmake, change CMakeCache.txt, and re-run cmake until you have the configuration you want. CMake is fairly sophisticated and can make reasonable guesses for many of the options. Once this configuration process is complete, run ''make'' and the appropriate binaries will be built in the directory MyXdmf/Linux/bin. For each architecture, create a new directory and repeat the process. This allows you to keep all platforms synchronized to the same source code base.Depending on the configuration you will see the following files : * libXdmf.[a so dll] C++ class library for XDMF * _Xdmf.[so dll] Python interface * libXdmfTCL.[so dll] Tcl interface * XdmfFormatExample Executable to write/read XDMF file The Python interface has been built with the shadow classes. This means that accessing XDMF via Python done in an Object Oriented manner just like in C++. To use the Object Oriented interface, you need to copy Xdmf.py ( found in <nowiki>.../Xdmf/libsrc/Xdmf.py</nowiki>) somewhere in your Python path. 52d2dd0106c3675113988f1a17e3138543680bfc 119 118 2014-08-19T19:21:57Z Dave.demarle 5 Dave.demarle moved page [[Get Xdmf]] to [[Get Xdmf original]] without leaving a redirect wikitext text/x-wiki == '''Obtaining and Installing XDMF''' == <pre style="color: red"> These instruction pertain to Xdmf version 1. </pre> The eXtensible Data Model and Format (XDMF) is installed and maintained, along with the rest of the Interdisciplinary Computing Environment, on the HPC systems at the ARL MSRC. If you need access on other platforms, obtain the source via CVS and follow the installation instructions. XDMF has been built and tested on a variety of UNIX platforms and on Win32 and Cygwin. CVS Access to the XDMF Source Code Repository XDMF is obtained via CVS access to the XDMF source code repository as a user (anonymous, read-only access). One of the advantages of CVS access is that you can incrementally update your repository without having to retrieve the entire source distribution. The following assumes that you have a basic knowledge of CVS. Anonymous User Read-Only Access You can obtain read-only access to the CVS repository as follows. cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login (respond with password xdmf) Follow this command by checking out the source code: cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf This CVS tree is Xdmf. Checkout the CVS in a clean directory as it will create an Xdmf directory and possibly overwrite an existing Xdmf tree. You will also need CMake which is a new cross platform build tool. '''Installation''' XDMF depends on Expat and HDF5. While a version of Expat and HDF5 comes with the the XDMF source, you might want to get the latest version of these packages. Obtain Expat from here . Obtain HDF from here. You'll also want Python (version 2.5 or later). Obtain Python from [http://www.python.org Python.Org]. If you want to use the scientific visualization tools, you'll need vtk ( version 5.0 or later ). Obtain vtk from [http://public.kitware.com Kitware.Com]. Xdmf uses CMake for installation. Pre-Built binaries of CMake are available for many platforms, or you can install from source. The advantage of CMake is that it provides a consistent build system for UNIX and Win32. For this reason, we replaced the previous autoconf <nowiki>(./configure --prefix...)</nowiki> method with CMake. Once you�ve installed the necessary support packages, begin to build Xdmf for your platform. For example, suppose you wish to build a Linux version : # mkdir MyXdmf # cd MyXdmf # cvs <nowiki>-d ...</nowiki> login # cvs <nowiki>-d ...</nowiki> co Xdmf This creates an Xdmf directory of the source code # mkdir Linux # cd Linux # cmake ../Xdmf CMake comes with several different commands. The two most important are cmake (the command line version) and ccmake (a curses based gui version). Both versions create a Makefile in the current directory and a file ''CMakeCache.txt'' that contains the compile time options. Options include things like additional compiler flags, where to find various packages (like HDF and expat), and which parts to build ( shared objects, python interface, etc.). As you change the CMakeCache.txt file either by hand or via the gui, additional options may appear. For example, if you decide to build the Python interface, new options for the location of Python include files and libraries will appear in the CMakeCache.txt file after you re-run cmake. In short, you run cmake, change CMakeCache.txt, and re-run cmake until you have the configuration you want. CMake is fairly sophisticated and can make reasonable guesses for many of the options. Once this configuration process is complete, run ''make'' and the appropriate binaries will be built in the directory MyXdmf/Linux/bin. For each architecture, create a new directory and repeat the process. This allows you to keep all platforms synchronized to the same source code base.Depending on the configuration you will see the following files : * libXdmf.[a so dll] C++ class library for XDMF * _Xdmf.[so dll] Python interface * libXdmfTCL.[so dll] Tcl interface * XdmfFormatExample Executable to write/read XDMF file The Python interface has been built with the shadow classes. This means that accessing XDMF via Python done in an Object Oriented manner just like in C++. To use the Object Oriented interface, you need to copy Xdmf.py ( found in <nowiki>.../Xdmf/libsrc/Xdmf.py</nowiki>) somewhere in your Python path. 52d2dd0106c3675113988f1a17e3138543680bfc Get Xdmf 0 20 120 2014-08-19T19:28:31Z Dave.demarle 5 add updated content wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on boost, zlib and hdf5. You must build those projects before you can build xdmf. To use Xdmf from Python, Tcl or Java you will also need swig. To obtain xdmf: * git clone git://public.kitware.com/Xdmf2.git XDMF * mkdir build * cd build * ccmake ../XDMF * make To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake. Xdmf is also mirrored in VTK. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration. c11beada65ae87d7c97850ebf6fe5e1ef4edc0cc 123 120 2014-08-19T20:42:37Z Dave.demarle 5 wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on zlib and hdf5 and had a header only dependency on boost. You must obtain and build those projects before you can build xdmf. To use Xdmf from Python, Tcl or Java you will also need swig. To obtain xdmf: * git clone git://public.kitware.com/Xdmf2.git XDMF * mkdir build * cd build * ccmake ../XDMF * make To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake. Xdmf is also mirrored in VTK. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration. ae03c8e8bbbf57cd42f85f25882c450caa3705f2 Examples/imagedata 0 16 122 98 2014-08-19T19:35:35Z Dave.demarle 5 wikitext text/x-wiki The following will read in an array of floats from h5 with the values associated with the points. <code format="XML"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Domain> <Grid Name="Particle Images" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" Dimensions="400 300 300"/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Name="Origin" Dimensions="3" NumberType="Float" Precision="4" Format="XML"> 0 0 0 </DataItem> <DataItem Name="Spacing" Dimensions="3" NumberType="Float" Precision="4" Format="XML"> 1 1 1 </DataItem> </Geometry> <Attribute Name="second 0" AttributeType="Scalar" Center="Node"> <DataItem Format="HDF" NumberType="UInt" Precision="2" Dimensions="400 300 300">test.hdf:/images/0/image</DataItem> </Attribute> </Grid> </Domain> </Xdmf> </code> The following will read in an array of floats from h5 with the values associated with the cells. <code format="XML"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Domain> <Grid Name="Particle Images" GridType="Uniform"> <Topology TopologyType="3DCORECTMesh" Dimensions="401 301 301"/> <Geometry GeometryType="ORIGIN_DXDYDZ"> <DataItem Name="Origin" Dimensions="3" NumberType="Float" Precision="4" Format="XML"> 0 0 0 </DataItem> <DataItem Name="Spacing" Dimensions="3" NumberType="Float" Precision="4" Format="XML"> 1 1 1 </DataItem> </Geometry> <Attribute Name="second 0" AttributeType="Scalar" Center="Cell"> <DataItem Format="HDF" NumberType="UInt" Precision="2" Dimensions="400 300 300">test.hdf:/images/0/image</DataItem> </Attribute> </Grid> </Domain> </Xdmf> </code> 9d0dadd993970cf2441bbb3281728956802385a8 V2 To V3 0 21 124 2014-09-02T15:36:29Z FelipeB 19 Created page with " For more information about the V3 read [[Version 3]] [[V3_Road_Feature_Request|Feature Requests for V3]] TODO list for the transition from V2 to V3: * xdmf.org needs an up..." wikitext text/x-wiki For more information about the V3 read [[Version 3]] [[V3_Road_Feature_Request|Feature Requests for V3]] TODO list for the transition from V2 to V3: * xdmf.org needs an update and currently has documentation for v2. There have been a few changes on what is and is not accepted between versions. For example the "NumberOfElement" tag in the "Topology" is not accepted any more (use "Dimensions" instead). the We are going to be updating it to cover v3 in the near future. * If we save using the V3 and all the data is stored in the xml (in the case of a 2DCoRectMesh grid with no data) an empty h5 file is generated. Reported in [http://public.kitware.com/Bug/view.php?id=15122] bcc852d889299269912e1c39b680b12841aeb061 126 124 2014-11-07T15:23:11Z Burns 17 wikitext text/x-wiki For more information about the V3 read [[Version 3]] [[V3_Road_Feature_Request|Feature Requests for V3]] TODO list for the transition from V2 to V3: * xdmf.org needs an update and currently has documentation for v2. There have been a few changes on what is and is not accepted between versions. For example the "NumberOfElement" tag in the "Topology" is not accepted any more (use "Dimensions" instead). the We are going to be updating it to cover v3 in the near future. * If we save using the V3 and all the data is stored in the xml (in the case of a 2DCoRectMesh grid with no data) an empty h5 file is generated. Reported in [http://public.kitware.com/Bug/view.php?id=15122] ** Will be fixed in the next release. 0beb6e309be3cb2acfc2ec4fa98983340cda676a 150 126 2014-11-20T16:56:28Z Burns 17 wikitext text/x-wiki For more information about the V3 read [[Version 3]] [[V3_Road_Feature_Request|Feature Requests for V3]] TODO list for the transition from V2 to V3: * If we save using the V3 and all the data is stored in the xml (in the case of a 2DCoRectMesh grid with no data) an empty h5 file is generated. Reported in [http://public.kitware.com/Bug/view.php?id=15122] ** Will be fixed in the next release. f9e7cb144b429904513696c1ab98ebe96b7530e3 Xdmf2 API Archive 0 22 128 2014-11-07T15:36:50Z Burns 17 Created page with "'''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF li..." wikitext text/x-wiki '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parse strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement ( XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1 ) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfTime''' When UpdateInformation() gets called for a Grid, an XdmfTime object is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there is a &lt;Time&gt; element in the Grid the object is populated. If the Grid is Non-Uniform (i.e. Collection, Tree), the children are updated as well. If the parent is TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the appropriate value set. Methods : XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0) This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten. XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax) this checks to see if the Time is entirely in Min/Max. Since this is a float comparison, I added an Epsilon member to XdmfTime with default value = 1e-7. This may be changed via XdmfTime::SetEpsilon() XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill) This populates the array with the direct children that are entirely in min/max. For example if the range is 0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL. '''XdmfHDF''' In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) # If an array is given a HeavyDataSetName, that is # where it will be written p.setHeavyDataSetName('MyData.h5:/Pressure') g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file 82109b846a11855a28c933c8ee00033aff7e70ce 129 128 2014-11-07T15:37:19Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] '''XDMF API''' While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. The XDMF library give access to a C++ class library that is also wrapped for access from scripting languages like Python. All XDMF Objects are derived from XdmfObject. Via this object, debug information can be turned on or off for each object or globally for all objects. The methods DebugOn/Off() and GlobalDebugOn/Off() perform these functions respectively. Most examples here are written in Python for clarity. '''XdmfDOM''' To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. XdmfDOM is a slightly higher abstraction of the Document Object Model (DOM). The DOM is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. The low level libxml2 nodes are typedefed as XdmfXmlNode. The XdmfDOM can parse strings or files : Status = XdmfDOM.Parse(MyXMLString) or Status = XdmfDOM.Parse(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) As with many XDMF objects, status is either XDMF_SUCCESS or XDMF_FAIL which is defined in XdmfObject.h. Once the XML has been parsed into the DOM, the tree can be navigated and modified. There are several useful query mechanisms in XdmfDOM. The first method finds the n<nowiki></nowiki>th instance of an element below a parent node : XdmfXmlNode FindElement ( XdmfConstString TagName, XdmfInt32 Index=0, XdmfXmlNode Node=NULL, XdmfInt32 IgnoreInfo=1 ) If Node==NULL the root node is assumed to be the desired parent node. IgnoreInfo allows for all "Information" elements to be ignored. For example, to find the third Grid element under the Domain element : DomainNode = XdmfDOM.FindElemet("Domain") <nowiki>#</nowiki> Take all defaults GridNode = XdmfDOM.FindElement("Grid", 2, DomainNode) <nowiki>#</nowiki> Index is zero based By utilizing the XPath functionality of libxml2, the same Grid element can be found by : GridNode = XdmfDOM.FindElementByPath("/Xdmf/Domain/Grid[3]") <nowiki>#</nowiki> XPath is 1 based Once the desired node is found, it can be queried and modified : NumberOfChildElements = XdmfDOM.GetNumberOfChildren(GridNode) Name = XdmfDOM.GetAttribute(GridNode, "Name") SubGrid = XdmfDOM.InsertNew(GridNode, "Grid") Status = XdmfDOM.Set(SubGrid, "Name", "My SubGrid") And finally written back out : XmlString = XdmfDOM.Serialize(GridNode) or Status = XdmfDOM.Write("MyFile.xmf") '''XdmfElement''' Each element type in an XDMF XML file has a corresponding XDMF object implementation. All of these are children of XdmfElement. Each XdmfElement must be provided with an XdmfDOM with which to operate. On input, the UpdateInformation() method will initialize the basic structure of the element from the XML without reading any HeavyData. The Update() method will access the HeavyData. Each derived object from XdmfElement (XdmfGrid for example) will override these methods. GridNode = DOM.FindElementByPath("/Xdmf/Domain/Grid[3]") Grid = XdmfGrid() <nowiki>#</nowiki> Create Grid.SetDOM(DOM) Grid.SetElement(GridNode) Grid.UpdateInformation() <nowiki>#</nowiki> Update Light Structure Grid.Update() <nowiki>#</nowiki> Read HeavyData Once the DOM has been set for an XdmfElement, there are convenience methods such as Set() and Get() which are equivalent to the XdmfDOM methods. GridName = Grid.Get(<nowiki>"</nowiki>Name<nowiki>"</nowiki>) Is the same as DOM = Grid.GetDOM() GridNode = Grid.GetElement() GridName = DOM.Get(GridNode, "Name") For output, the XdmfElement methods Insert() and Build() are used. Each derived object in XDMF will assure that only the proper type of element is inserted. For example, it is illegal to insert a Domain element directly below a Grid element. Info = XdmfInformation() <nowiki>#</nowiki> Arbitrary Name=Value Facility Info.SetName("Time") Info.SetValue("0.0123") Grid = XdmfGrid() Grid.Set("Name", "My Grid") Grid.Insert(Info) Grid.Build() Results in &lt;Grid Name="My Grid"&gt; &lt;Information Name="Time" Value="0.0123" /&gt; &lt;/Grid&gt; The Build() method is recursive so that Build() will automatically be called for all child elements. '''XdmfArray''' The XdmfArray class is a self describing data structure. It is derived from the XdmfDataDesc class that gives it number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; XdmfInt64 total, dims<nowiki>[</nowiki>3<nowiki>]</nowiki>; XdmfArray <nowiki>*</nowiki>xyz = new XdmfArray; dims<nowiki>[</nowiki>0<nowiki>]</nowiki> = 10; dims<nowiki>[</nowiki>1<nowiki>]</nowiki> = 20; dims<nowiki>[</nowiki>2<nowiki>]</nowiki> = 30; total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->SetNumberType(XDMF_FLOAT64_TYPE) xyz->SetShape(3, dims); // KDim, JDim, IDim xyz->SetValues(0, x, total, 3, 1); // SetValues (XdmfInt64 Index, XdmfFloat64 <nowiki>*</nowiki>Values, // XdmfInt64 NumberOfValues, XdmfInt64 ArrayStride=1, // XdmfInt64 ValuesStride=1) xyz->SetValues(1, y, total, 3, 1); xyz->SetValues(2, z, total, 3, 1); When an XdmfArray is created, it is given a unique tag name. Array operations can be performed on XdmfArray data by using this name in an XdmfExpr(). The following Python program gives some examples. from Xdmf import * def Expression(*args) : e = '' for arg in args : if hasattr(arg, 'GetTagName') : e += arg.GetTagName() + ' ' else : e += arg + ' ' return XdmfExpr(e) if __name__ == '__main__' : a1 = XdmfArray() a1.SetNumberType(XDMF_FLOAT32_TYPE) a1.SetNumberOfElements(20) a1.Generate(1, 20) a2 = XdmfArray() a2.SetNumberType(XDMF_INT32_TYPE) a2.SetNumberOfElements(5) a2.Generate(2, 10) print 'a1 Values = ', a1.GetValues() print 'a1[2:10] = ' + Expression(a1 , '[ 2:10 ]').GetValues() print 'a2 Values = ', a2.GetValues() print 'a1[a2] = ' + Expression(a1 , '[', a2, ']').GetValues() print 'a1 + a2 = ' + Expression(a1 , ' + ', a2).GetValues() print 'a1 * a2 = ' + Expression(a1 , ' * ', a2).GetValues() a2.SetNumberType(XDMF_FLOAT32_TYPE) a2.SetNumberOfElements(20) a2.Generate(21, 40) print 'a2 Values = ', a2.GetValues() print 'a1 , a2 (Interlace) = ' + Expression(a1 , ' , ', a2).GetValues() print 'a1 , a2, a1 (Interlace) = ' + Expression(a1 , ' , ', a2, ' , ', a1).GetValues() print 'a1 ; a2 (Concat) = ' + Expression(a1 , ' ; ', a2).GetValues() print 'where(a1 > 10) = ' + Expression('Where( ', a1 , ' > 10)').GetValues() print 'a2[where(a1 > 10)] = ' + Expression(a2, '[Where( ', a1 , ' > 10)]').GetValues() While most of the functions are self explanatory the WHERE function is not. WHERE will return the indexes of the XdmfArray where a certain condition is true. In this example WHERE returns the indexes of XdmfArra y a1 where a1 is greater than 10. Notice that the XdmfExpr() function makes it easy to extract part of an XdmfArray. '''XdmfTime''' When UpdateInformation() gets called for a Grid, an XdmfTime object is added to the Grid with TimeType set to XDMF_TIME_UNSET. If there is a &lt;Time&gt; element in the Grid the object is populated. If the Grid is Non-Uniform (i.e. Collection, Tree), the children are updated as well. If the parent is TimeType="HyperSlab" then the child is XDMF_TIME_SINGLE with the appropriate value set. Methods : XdmfInt32 XdmfTime::Evaluate(XdmfGrid *Grid, XdmfArray *ArrayToFill = NULL, XdmfInt32 Descend = 0, XdmfInt32 Append = 0) This will populate the array with the valid times in the Grid. If Descend = 1 then it is recursive. If Append = 1 the values are appended to the given array not overwritten. XdmfInt32 XdmfTime::IsValid(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax) this checks to see if the Time is entirely in Min/Max. Since this is a float comparison, I added an Epsilon member to XdmfTime with default value = 1e-7. This may be changed via XdmfTime::SetEpsilon() XdmfInt32 XdmfGrid::FindGridsInTimeRange(XdmfFloat64 TimeMin, XdmfFloat64 TimeMax, XdmfArray *ArrayToFill) This populates the array with the direct children that are entirely in min/max. For example if the range is 0.0 to 0.5 with TimeMin=0.25 and TimeMax=1.25 this will return XDMF_FAIL. '''XdmfHDF''' In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. The XdmfHDF class simplifies access to HDF5 data, it is also derived from XdmfDataDesc. The following Python code demonstrates its use : from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. from Xdmf import * # Geometry GeometryArray = XdmfArray() GeometryArray.SetValues(0, Geometry) H5 = XdmfHDF() H5.CopyType(GeometryArray) H5.CopyShape(GeometryArray) # Open for Writing. This will truncate the file. H5.Open('Example1.h5:/Geometry', 'w') H5.Write(GeometryArray) H5.Close() # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.SetValues(0, Connectivity) H5 = XdmfHDF() H5.CopyType(ConnectivityArray) H5.CopyShape(ConnectivityArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Connectivity', 'rw') H5.Write(ConnectivityArray) H5.Close() # Values ValueArray = XdmfArray() ValueArray.SetValues(0, Values) H5 = XdmfHDF() H5.CopyType(ValueArray) H5.CopyShape(ValueArray) # Open for Reading and Writing. This will NOT truncate the file. H5.Open('Example1.h5:/Values', 'rw') H5.Write(ValueArray) H5.Close() For reading, XdmfHDF will allocate an array if none is specified : Status = H5.Open("Example1.h5:/Values", "rw") ValueArray = H5.Read() '''Reading XDMF''' Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single uniform Grid. Here is a Python example to read and print values. dom = XdmfDOM() dom.Parse("Points.xmf") ge = dom.FindElementByPath("/Xdmf/Domain/Grid") grid = XdmfGrid() grid.SetDOM(dom) grid.SetElement(ge) grid.UpdateInformation() grid.Update() top = grid.GetTopology() top.DebugOn() conn = top.GetConnectivity() print "Values = ", conn.GetValues() geo = grid.GetGeometry() points = geo.GetPoints() print "Geo Type = ", geo.GetGeometryTypeAsString(), " # Points = ", geo.GetNumberOfPoints() print "Points = ", points.GetValues(0, 6) '''Writing XDMF''' Using the Insert() and Build() methods, an XDMF dataset can be generated programmatically as well . Internally, as XDMF objects are inserted, the DOM is "decorated" with their pointers. In this manner, the api c an get a object from an node of the DOM if it has been created. For reading XDMF, this allows multiple references to the same DataItem not to result in additional IO. For writing, this allows Build() to work recursively. d = XdmfDOM() root = XdmfRoot() root.SetDOM(d) root.SetVersion(2.2) # Change the Version number because we can root.Build() # Information i = XdmfInformation() # Arbitrary Name=Value Facility i.SetName("Time") i.SetValue("0.0123") root.Insert(i) # XML DOM is used as the keeper of the structure # Insert() creates an XML node and inserts it under # the parent # Domain dm = XdmfDomain() root.Insert(dm) # Grid g = XdmfGrid() g.SetName("Structured Grid") # Topology t = g.GetTopology() t.SetTopologyType(XDMF_3DCORECTMESH) t.GetShapeDesc().SetShapeFromString('10 20 30') # Geometry geo = g.GetGeometry() geo.SetGeometryType(XDMF_GEOMETRY_ORIGIN_DXDYDZ) geo.SetOrigin(1, 2, 3) geo.SetDxDyDz(0.1, 0.2, 0.3) dm.Insert(g) # Attribute attr = XdmfAttribute() attr.SetName("Pressure") attr.SetAttributeCenter(XDMF_ATTRIBUTE_CENTER_CELL); attr.SetAttributeType(XDMF_ATTRIBUTE_TYPE_SCALAR); p = attr.GetValues() p.SetNumberOfElements(10 * 20 * 30) p.Generate(0.0, 1.0, 0, p.GetNumberOfElements() - 1) # If an array is given a HeavyDataSetName, that is # where it will be written p.setHeavyDataSetName('MyData.h5:/Pressure') g.Insert(attr) # Update XML and Write Values to DataItems root.Build() # DataItems > 100 values are heavy print d.Serialize() # prints to stdout d.Write('junk.xmf') # write to file d50586876a68e6b3150117ce287e1ad9b77279a8 Xdmf3 Python API 0 23 131 2014-11-07T16:53:02Z Burns 17 Created page with "[[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that ..." wikitext text/x-wiki [[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. All XDMF Objects are derived from XdmfItem. ===XdmfDomain=== To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. The Domain is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. A Domain can be created inside the code via the New function: domain = XdmfDomain.New() A reader can be used to produce a domain from an existing file: reader = XdmfReader.New() domain = reader.read(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) Once the XML has been parsed into the Domain, the tree can be navigated and modified. The domain is the root of the Xdmf tree and by accessing its children via XdmfDomain::getUnstructuredGrid(unsigned int) and similar functions. ungrid = domain.getUnstructuredGrid(0) The same grid can also be fetched by name. ungrid = domain.getUnstructuredGrid(<nowiki>"</nowiki>Unstructured Grid<nowiki>"</nowiki>) Once you have the child object, that child has its own functions that can be used to modify or retrieve attributes or children. originalName = ungrid.getName() ungrid.setName(<nowiki>"</nowiki>New Name<nowiki>"</nowiki>) When finished building and modifying the XdmfTree it can then be written out to file with an XdmfWriter visitor. writer = XdmfWriter.New(<nowiki>"</nowiki>outfile.xmf<nowiki>"</nowiki>) domain.accept(writer) ===XdmfArray=== The XdmfArray class is a self describing data structure. It contains descriptions for its internal number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: x = [1, 2, 3, ..] y = [1, 2, 3, ..] z = [1, 2, 3, ..] dims = UInt32Vector() dims.push_back(10) dims.push_back(20) dims.push_back(30) total = 10 * 20 * 30 xyz = XdmfArray.New() xyz.initialize(XdmfArrayType.Float64(), dims); // KDim, JDim, IDim xyz.insertAsFloat64(0, x, 0, total, 3, 1); // insert<nowiki><T></nowiki>(unsigned int index, T <nowiki>*</nowiki>Values, // unsigned int NumberOfValues, unsigned int ArrayStride=1, // unsigned int ValuesStride=1) xyz.insertAsFloat64(1, y, 0, total, 3, 1); xyz.insertAsFloat64(2, z, 0, total, 3, 1); ===XdmfTime=== When modifying the Xdmf Tree, XdmfTime objects can be added to grids in order to specify timestamps. time = XdmfTime.New(5.0) ungrid.setTime(time) ===XdmfHDF=== In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. Passing an XdmfHDF5Writer to an array will write its contents to the specified hdf5 file. A controller object is created to handle the data description and allows the array to read the data back in if needed. The default write mode creates a new hdf5 dataspace for each written array. HDF5 write modes include: * Default * Overwrite * Append * Hyperslab from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. heavywriter = XdmfHDF5Writer.New(<nowiki>"example.h5"</nowiki>) # Geometry GeometryArray = XdmfArray() GeometryArray.insertAsFloat64(0, Geometry) GeometryArray.accept(heavywriter) # Coneectivity ConnectivityArray = XdmfArray() ConnectivityArray.insertAsFloat64(0, Connectivity) ConnectivityArray.accept(heavywriter) # Values ValueArray = XdmfArray() ValueArray.insertAsFloat64(0, Values) ValueArray.accept(heavywriter) When reading, if reading from an XML file where the arrays have the hdf5 data sets specified, controllers will automatically be created for all arrays with a heavy data description. To access the data in heavy data XdmfArray::read() must be called. If it is required to link heavy data manually a heavy data controller can be created manually and added to an array. newPath = "File path to hdf5 file goes here" newSetPath = "path to the set goes here" readType = XdmfArrayType.Int32() #Xdmf provides wrappers for C++ types #in this case std::vector<unsigned int> readStarts = UInt32Vector() #Three dimensions, all starting at index 0 readStarts.push_back(0) readStarts.push_back(0) readStarts.push_back(0) readStrides = UInt32Vector() #Three dimensions, no skipping between index readStrides.push_back(1) readStrides.push_back(1) readStrides.push_back(1) readCounts = UInt32Vector() #Three dimensions, reading 10 values from each readCounts.push_back(10) readCounts.push_back(10) readCounts.push_back(10) readDataSize = UInt32Vector() #three dimensins, each with 20 maximum values readDataSize.push_back(20) readDataSize.push_back(20) readDataSize.push_back(20) controller = XdmfHDF5Controller.New( newPath, newSetPath, readType, readStarts, readStrides, readCounts, readDataSize) array.insert(controller) array.read() ===Reading XDMF=== Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single Grid. Here is a Python example to read and print values. reader = XdmfReader.New() domain = reader.read(<nowiki>"Points.xmf"</nowiki>) grid = domain.getUnstructuredGrid(0) topology = grid.getTopology() print "Values = ", topology.getValuesString() geometry = grid.getGeometry() print "Geo Type = ", geo.getType().getName(), " # Points = ", geometry.getNumberOfPoints() print "Points = ", geometry.getValuesString() ===Writing XDMF=== Using the insert() and set() methods, an XDMF dataset can be generated programmatically as well. An object tree mirroring the XML is built as Xdmf objects are attached to each other. Since this is handled via shared pointers the objects are not duplicated if there are multiple instances of that object in the tree and the user does not have to worry about memory cleanup. root = XdmfDomain.New() # Information i = XdmfInformation.New() # Arbitrary Name=Value Facility i.setName("Time") i.setValue("0.0123") root.insert(i) # XdmfDomain is the root of the tree # insert adds the information we just created as a leaf # Dimensions dimensions = XdmfArray.New() dimensions.pushBackAsUInt32(10) dimensions.pushBackAsUInt32(20) dimensions.pushBackAsUInt32(30) # Origin origin = XdmfArray.New() origin.pushBackAsUInt32(1) origin.pushBackAsUInt32(2) origin.pushBackAsUInt32(3) # Brick Size brick = XdmfArray.New() brick.pushBackAsUInt32(1) brick.pushBackAsUInt32(2) brick.pushBackAsUInt32(3) # Grid g = XdmfRegularGrid.New(brick, dimensions, origin) g.setName("Structured Grid") root.Insert(g) # Attribute attr = XdmfAttribute.New() attr.setName("Pressure") attr.setAttributeCenter(XdmfAttributeCenter::Cell()); attr.setAttributeType(XdmfAttributeType::Scalar()); attr.initializeAsFloat64(10 * 20 * 30) pressureVals = {0, 1, 2, 3, 4, 5, ...} attr.insert(0, pressureVals) # The heavy data set name is determined by the writer if not set g.insert(attr) # Generate a writer writer = XdmfWriter.New(<nowiki>"output.xmf"</nowiki>) domain.accept(writer) e6fbc040e98eefc18be96bb133e242ce8ebc0a91 132 131 2014-11-07T16:55:38Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. All XDMF Objects are derived from XdmfItem. ===XdmfDomain=== To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. The Domain is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. A Domain can be created inside the code via the New function: domain = XdmfDomain.New() A reader can be used to produce a domain from an existing file: reader = XdmfReader.New() domain = reader.read(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) Once the XML has been parsed into the Domain, the tree can be navigated and modified. The domain is the root of the Xdmf tree and by accessing its children via XdmfDomain::getUnstructuredGrid(unsigned int) and similar functions. ungrid = domain.getUnstructuredGrid(0) The same grid can also be fetched by name. ungrid = domain.getUnstructuredGrid(<nowiki>"</nowiki>Unstructured Grid<nowiki>"</nowiki>) Once you have the child object, that child has its own functions that can be used to modify or retrieve attributes or children. originalName = ungrid.getName() ungrid.setName(<nowiki>"</nowiki>New Name<nowiki>"</nowiki>) When finished building and modifying the XdmfTree it can then be written out to file with an XdmfWriter visitor. writer = XdmfWriter.New(<nowiki>"</nowiki>outfile.xmf<nowiki>"</nowiki>) domain.accept(writer) ===XdmfArray=== The XdmfArray class is a self describing data structure. It contains descriptions for its internal number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: x = [1, 2, 3, ..] y = [1, 2, 3, ..] z = [1, 2, 3, ..] dims = UInt32Vector() dims.push_back(10) dims.push_back(20) dims.push_back(30) total = 10 * 20 * 30 xyz = XdmfArray.New() xyz.initialize(XdmfArrayType.Float64(), dims); // KDim, JDim, IDim xyz.insertAsFloat64(0, x, 0, total, 3, 1); // insert<nowiki><T></nowiki>(unsigned int index, T <nowiki>*</nowiki>Values, // unsigned int NumberOfValues, unsigned int ArrayStride=1, // unsigned int ValuesStride=1) xyz.insertAsFloat64(1, y, 0, total, 3, 1); xyz.insertAsFloat64(2, z, 0, total, 3, 1); ===XdmfTime=== When modifying the Xdmf Tree, XdmfTime objects can be added to grids in order to specify timestamps. time = XdmfTime.New(5.0) ungrid.setTime(time) ===XdmfHDF=== In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. Passing an XdmfHDF5Writer to an array will write its contents to the specified hdf5 file. A controller object is created to handle the data description and allows the array to read the data back in if needed. The default write mode creates a new hdf5 dataspace for each written array. HDF5 write modes include: * Default * Overwrite * Append * Hyperslab from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. heavywriter = XdmfHDF5Writer.New(<nowiki>"example.h5"</nowiki>) # Geometry GeometryArray = XdmfArray() GeometryArray.insertAsFloat64(0, Geometry) GeometryArray.accept(heavywriter) # Connectivity ConnectivityArray = XdmfArray() ConnectivityArray.insertAsFloat64(0, Connectivity) ConnectivityArray.accept(heavywriter) # Values ValueArray = XdmfArray() ValueArray.insertAsFloat64(0, Values) ValueArray.accept(heavywriter) When reading, if reading from an XML file where the arrays have the hdf5 data sets specified, controllers will automatically be created for all arrays with a heavy data description. To access the data in heavy data XdmfArray::read() must be called. If it is required to link heavy data manually a heavy data controller can be created manually and added to an array. newPath = "File path to hdf5 file goes here" newSetPath = "path to the set goes here" readType = XdmfArrayType.Int32() #Xdmf provides wrappers for C++ types #in this case std::vector<unsigned int> readStarts = UInt32Vector() #Three dimensions, all starting at index 0 readStarts.push_back(0) readStarts.push_back(0) readStarts.push_back(0) readStrides = UInt32Vector() #Three dimensions, no skipping between index readStrides.push_back(1) readStrides.push_back(1) readStrides.push_back(1) readCounts = UInt32Vector() #Three dimensions, reading 10 values from each readCounts.push_back(10) readCounts.push_back(10) readCounts.push_back(10) readDataSize = UInt32Vector() #three dimensins, each with 20 maximum values readDataSize.push_back(20) readDataSize.push_back(20) readDataSize.push_back(20) controller = XdmfHDF5Controller.New( newPath, newSetPath, readType, readStarts, readStrides, readCounts, readDataSize) array.insert(controller) array.read() ===Reading XDMF=== Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single Grid. Here is a Python example to read and print values. reader = XdmfReader.New() domain = reader.read(<nowiki>"Points.xmf"</nowiki>) grid = domain.getUnstructuredGrid(0) topology = grid.getTopology() print "Values = ", topology.getValuesString() geometry = grid.getGeometry() print "Geo Type = ", geo.getType().getName(), " # Points = ", geometry.getNumberOfPoints() print "Points = ", geometry.getValuesString() ===Writing XDMF=== Using the insert() and set() methods, an XDMF dataset can be generated programmatically as well. An object tree mirroring the XML is built as Xdmf objects are attached to each other. Since this is handled via shared pointers the objects are not duplicated if there are multiple instances of that object in the tree and the user does not have to worry about memory cleanup. root = XdmfDomain.New() # Information i = XdmfInformation.New() # Arbitrary Name=Value Facility i.setName("Time") i.setValue("0.0123") root.insert(i) # XdmfDomain is the root of the tree # insert adds the information we just created as a leaf # Dimensions dimensions = XdmfArray.New() dimensions.pushBackAsUInt32(10) dimensions.pushBackAsUInt32(20) dimensions.pushBackAsUInt32(30) # Origin origin = XdmfArray.New() origin.pushBackAsUInt32(1) origin.pushBackAsUInt32(2) origin.pushBackAsUInt32(3) # Brick Size brick = XdmfArray.New() brick.pushBackAsUInt32(1) brick.pushBackAsUInt32(2) brick.pushBackAsUInt32(3) # Grid g = XdmfRegularGrid.New(brick, dimensions, origin) g.setName("Structured Grid") root.Insert(g) # Attribute attr = XdmfAttribute.New() attr.setName("Pressure") attr.setAttributeCenter(XdmfAttributeCenter::Cell()); attr.setAttributeType(XdmfAttributeType::Scalar()); attr.initializeAsFloat64(10 * 20 * 30) pressureVals = {0, 1, 2, 3, 4, 5, ...} attr.insert(0, pressureVals) # The heavy data set name is determined by the writer if not set g.insert(attr) # Generate a writer writer = XdmfWriter.New(<nowiki>"output.xmf"</nowiki>) domain.accept(writer) 0518535279281a7e79b7edd02a8d8903fc257f24 133 132 2014-11-07T17:09:52Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. All XDMF Objects are derived from XdmfItem. ===XdmfDomain=== To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. The Domain is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. A Domain can be created inside the code via the New function: domain = XdmfDomain.New() A reader can be used to produce a domain from an existing file: reader = XdmfReader.New() domain = reader.read(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>) Once the XML has been parsed into the Domain, the tree can be navigated and modified. The domain is the root of the Xdmf tree and by accessing its children via XdmfDomain::getUnstructuredGrid(unsigned int) and similar functions. ungrid = domain.getUnstructuredGrid(0) The same grid can also be fetched by name. ungrid = domain.getUnstructuredGrid(<nowiki>"</nowiki>Unstructured Grid<nowiki>"</nowiki>) Once you have the child object, that child has its own functions that can be used to modify or retrieve attributes or children. originalName = ungrid.getName() ungrid.setName(<nowiki>"</nowiki>New Name<nowiki>"</nowiki>) When finished building and modifying the XdmfTree it can then be written out to file with an XdmfWriter visitor. writer = XdmfWriter.New(<nowiki>"</nowiki>outfile.xmf<nowiki>"</nowiki>) domain.accept(writer) ===XdmfArray=== The XdmfArray class is a self describing data structure. It contains descriptions for its internal number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: x = [1, 2, 3, ..] y = [1, 2, 3, ..] z = [1, 2, 3, ..] dims = UInt32Vector() dims.push_back(10) dims.push_back(20) dims.push_back(30) total = 10 * 20 * 30 xyz = XdmfArray.New() xyz.initialize(XdmfArrayType.Float64(), dims); // KDim, JDim, IDim xyz.insertAsFloat64(0, x, 0, total, 3, 1); // insert<nowiki><T></nowiki>(unsigned int index, T <nowiki>*</nowiki>Values, // unsigned int NumberOfValues, unsigned int ArrayStride=1, // unsigned int ValuesStride=1) xyz.insertAsFloat64(1, y, 0, total, 3, 1); xyz.insertAsFloat64(2, z, 0, total, 3, 1); ===XdmfTime=== When modifying the Xdmf Tree, XdmfTime objects can be added to grids in order to specify timestamps. time = XdmfTime.New(5.0) ungrid.setTime(time) ===XdmfHDF=== In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. Passing an XdmfHDF5Writer to an array will write its contents to the specified hdf5 file. A controller object is created to handle the data description and allows the array to read the data back in if needed. The default write mode creates a new hdf5 dataspace for each written array. HDF5 write modes include: * Default * Overwrite * Append * Hyperslab from Xdmf import <nowiki>*</nowiki> Geometry = "-1.75 -1.25 0 -1.25 -1.25 0 -0.75 Connectivity = "3 2 5 1 . Values = "100 200 300 .. heavywriter = XdmfHDF5Writer.New(<nowiki>"example.h5"</nowiki>) # Geometry GeometryArray = XdmfGeometry.New() GeometryArray.insertAsFloat64(0, Geometry) GeometryArray.accept(heavywriter) # Connectivity ConnectivityArray = XdmfTopology.New() ConnectivityArray.insertAsFloat64(0, Connectivity) ConnectivityArray.accept(heavywriter) # Values ValueArray = XdmfArray.New() ValueArray.insertAsFloat64(0, Values) ValueArray.accept(heavywriter) When reading, if reading from an XML file where the arrays have the hdf5 data sets specified, controllers will automatically be created for all arrays with a heavy data description. To access the data in heavy data XdmfArray::read() must be called. If it is required to link heavy data manually a heavy data controller can be created manually and added to an array. newPath = "File path to hdf5 file goes here" newSetPath = "path to the set goes here" readType = XdmfArrayType.Int32() #Xdmf provides wrappers for C++ types #in this case std::vector<unsigned int> readStarts = UInt32Vector() #Three dimensions, all starting at index 0 readStarts.push_back(0) readStarts.push_back(0) readStarts.push_back(0) readStrides = UInt32Vector() #Three dimensions, no skipping between index readStrides.push_back(1) readStrides.push_back(1) readStrides.push_back(1) readCounts = UInt32Vector() #Three dimensions, reading 10 values from each readCounts.push_back(10) readCounts.push_back(10) readCounts.push_back(10) readDataSize = UInt32Vector() #three dimensins, each with 20 maximum values readDataSize.push_back(20) readDataSize.push_back(20) readDataSize.push_back(20) controller = XdmfHDF5Controller.New( newPath, newSetPath, readType, readStarts, readStrides, readCounts, readDataSize) array.insert(controller) array.read() ===Reading XDMF=== Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single Grid. Here is a Python example to read and print values. reader = XdmfReader.New() domain = reader.read(<nowiki>"Points.xmf"</nowiki>) grid = domain.getUnstructuredGrid(0) topology = grid.getTopology() print "Values = ", topology.getValuesString() geometry = grid.getGeometry() print "Geo Type = ", geo.getType().getName(), " # Points = ", geometry.getNumberOfPoints() print "Points = ", geometry.getValuesString() ===Writing XDMF=== Using the insert() and set() methods, an XDMF dataset can be generated programmatically as well. An object tree mirroring the XML is built as Xdmf objects are attached to each other. Since this is handled via shared pointers the objects are not duplicated if there are multiple instances of that object in the tree and the user does not have to worry about memory cleanup. root = XdmfDomain.New() # Information i = XdmfInformation.New() # Arbitrary Name=Value Facility i.setName("Time") i.setValue("0.0123") root.insert(i) # XdmfDomain is the root of the tree # insert adds the information we just created as a leaf # Dimensions dimensions = XdmfArray.New() dimensions.pushBackAsUInt32(10) dimensions.pushBackAsUInt32(20) dimensions.pushBackAsUInt32(30) # Origin origin = XdmfArray.New() origin.pushBackAsUInt32(1) origin.pushBackAsUInt32(2) origin.pushBackAsUInt32(3) # Brick Size brick = XdmfArray.New() brick.pushBackAsUInt32(1) brick.pushBackAsUInt32(2) brick.pushBackAsUInt32(3) # Grid g = XdmfRegularGrid.New(brick, dimensions, origin) g.setName("Structured Grid") root.Insert(g) # Attribute attr = XdmfAttribute.New() attr.setName("Pressure") attr.setAttributeCenter(XdmfAttributeCenter::Cell()); attr.setAttributeType(XdmfAttributeType::Scalar()); attr.initializeAsFloat64(10 * 20 * 30) pressureVals = {0, 1, 2, 3, 4, 5, ...} attr.insert(0, pressureVals) # The heavy data set name is determined by the writer if not set g.insert(attr) # Generate a writer writer = XdmfWriter.New(<nowiki>"output.xmf"</nowiki>) domain.accept(writer) 369bcef7b7c9fd349a6a17e5ad54aa118654144f Xdmf3 C++ API 0 24 134 2014-11-07T17:49:16Z Burns 17 Created page with "[[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that..." wikitext text/x-wiki [[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== While use of the XDMF API is not necessary to produce or consume valid XDMF datasets, there are many convenience features that make it attractive. All XDMF Objects are derived from XdmfItem. ===XdmfDomain=== To understand access to XDMF data, understanding of the XdmfDOM is critical. XDMF uses the libxml2 library to parse and generate XML documents. The Domain is an in-memory tree structure that represents the XML file. Nodes of the tree are added, deleted, queried and serialized. A Domain can be created inside the code via the New function: shared_ptr<nowiki><XdmfDomain></nowiki> domain = XdmfDomain::New(); A reader can be used to produce a domain from an existing file: shared_ptr<nowiki><XdmfReader></nowiki> reader = XdmfReader::New(); shared_ptr<nowiki><XdmfDomain></nowiki> domain = shared_dynamic_cast<nowiki><XdmfDomain></nowiki>(reader->read(<nowiki>"</nowiki>MyXMLFile.xmf<nowiki>"</nowiki>)); Once the XML has been parsed into the Domain, the tree can be navigated and modified. The domain is the root of the Xdmf tree and by accessing its children via XdmfDomain::getUnstructuredGrid(unsigned int) and similar functions. shared_ptr<nowiki><XdmfUnstructuredGrid></nowiki> ungrid = domain->getUnstructuredGrid(0); The same grid can also be fetched by name. shared_ptr<nowiki><XdmfUnstructuredGrid></nowiki> ungrid = domain->getUnstructuredGrid(<nowiki>"</nowiki>Unstructured Grid<nowiki>"</nowiki>); Once you have the child object, that child has its own functions that can be used to modify or retrieve attributes or children. std::string originalName = ungrid->getName(); ungrid->setName(<nowiki>"</nowiki>New Name<nowiki>"</nowiki>); When finished building and modifying the XdmfTree it can then be written out to file with an XdmfWriter visitor. shared_ptr<nowiki><XdmfWriter></nowiki> writer = XdmfWriter::New(<nowiki>"</nowiki>outfile.xmf<nowiki>"</nowiki>); domain->accept(writer); ===XdmfArray=== The XdmfArray class is a self describing data structure. It contains descriptions for its internal number type, precision, and shape (rank and dimensions). Many XDMF classes require an XdmfArray as input to methods. The following C++ example demonstrates creating an interlaced XYZ array from three separate variables: float *x, *y, *z; unsigned int total; std::vector<unsigned int> dims; dims.push_back(10); dims.push_back(20); dims.push_back(30); shared_ptr<nowiki><XdmfArray></nowiki> xyz = XdmfArray::New(); total = 10 <nowiki>*</nowiki> 20 <nowiki>*</nowiki> 30; xyz->initialize(XdmfArrayType::Float64(), dims); // KDim, JDim, IDim xyz->insert(0, x, 0, total, 3, 1); // insert<nowiki><T></nowiki>(unsigned int index, T <nowiki>*</nowiki>Values, // unsigned int NumberOfValues, unsigned int ArrayStride=1, // unsigned int ValuesStride=1) xyz->insert(1, y, 0, total, 3, 1); xyz->insert(2, z, 0, total, 3, 1); ===XdmfTime=== When modifying the Xdmf Tree, XdmfTime objects can be added to grids in order to specify timestamps. shared_ptr<nowiki><XdmfTime></nowiki> time = XdmfTime::New(5.0); ungrid->setTime(time); ===XdmfHDF=== In XDMF, Light data is stored in XML while the Heavy data is typically stored in an HDF5 file. Passing an XdmfHDF5Writer to an array will write its contents to the specified hdf5 file. A controller object is created to handle the data description and allows the array to read the data back in if needed. The default write mode creates a new hdf5 dataspace for each written array. HDF5 write modes include: * Default * Overwrite * Append * Hyperslab double * Geometry = [-1.75, -1.25, 0, -1.25, -1.25, 0, -0.75, ..]; unsigned int * Connectivity = [3, 2, 5, 1, ..]; int Values = [100, 200, 300, ..]; shared_ptr<nowiki><XdmfHDF5Writer></nowiki> heavywriter = XdmfHDF5Writer->New(<nowiki>"example.h5"</nowiki>); // Geometry shared_ptr<nowiki><XdmfGeometry></nowiki> GeometryArray = XdmfGeometry::New(); GeometryArray->insert(0, Geometry, geometryNumValues); GeometryArray->accept(heavywriter); // Coneectivity shared_ptr<nowiki><XdmfTopology></nowiki> ConnectivityArray = XdmfTopology::New(); ConnectivityArray->insert(0, Connectivity, connectivityNumValues); ConnectivityArray->accept(heavywriter); // Values shared_ptr<nowiki><XdmfArray></nowiki> ValueArray = XdmfArray::New(); ValueArray->insert(0, Values, numValues); ValueArray->accept(heavywriter); When reading, if reading from an XML file where the arrays have the hdf5 data sets specified, controllers will automatically be created for all arrays with a heavy data description. To access the data in heavy data XdmfArray::read() must be called. If it is required to link heavy data manually a heavy data controller can be created manually and added to an array. std::string newPath = "File path to hdf5 file goes here"; std::string newSetPath = "path to the set goes here"; shared_ptr<nowiki><const XdmfArrayType></nowiki> readType = XdmfArrayType::Int32(); std::vector<nowiki><unsigned int></nowiki> readStarts; //Three dimensions, all starting at index 0 readStarts.push_back(0); readStarts.push_back(0); readStarts.push_back(0); std::vector<nowiki><unsigned int></nowiki> readStrides; //Three dimensions, no skipping between index readStrides.push_back(1); readStrides.push_back(1); readStrides.push_back(1); std::vector<nowiki><unsigned int></nowiki> readCounts; //Three dimensions, reading 10 values from each readCounts.push_back(10); readCounts.push_back(10); readCounts.push_back(10); std::vector<nowiki><unsigned int></nowiki> readDataSize; //Three dimensins, each with 20 maximum values readDataSize.push_back(20); readDataSize.push_back(20); readDataSize.push_back(20); shared_ptr<nowiki><XdmfHDF5Controller></nowiki> controller = XdmfHDF5Controller::New( newPath, newSetPath, readType, readStarts, readStrides, readCounts, readDataSize); array->insert(controller); array->read(); ===Reading XDMF=== Putting all of this together, assume Points.xmf is a valid XDMF XML file with a single Grid. Here is a C++ example to read and print values. shared_ptr<nowiki><XdmfReader></nowiki> reader = XdmfReader->New(); shared_ptr<nowiki><XdmfDomain></nowiki> domain = shared_dynamic_cast<nowiki><XdmfDomain></nowiki>(reader->.read(<nowiki>"Points.xmf"</nowiki>)); shared_ptr<nowiki><XdmfUnstructuredGrid></nowiki> grid = domain->getUnstructuredGrid(0); shared_ptr<nowiki><XdmfTopology></nowiki> topology = grid->getTopology(); printf("Values = %s\n", topology->getValuesString().c_str()); shared_ptr<nowiki><XdmfGeometry></nowiki> geometry = grid->getGeometry(); printf("Geo Type = %s # Points = %u\n", geometry->getType()->getName().c_str(), geometry->getNumberOfPoints()); printf("Points = %s\n", geometry->getValuesString()); ===Writing XDMF=== Using the insert() and set() methods, an XDMF dataset can be generated programmatically as well. An object tree mirroring the XML is built as Xdmf objects are attached to each other. Since this is handled via shared pointers the objects are not duplicated if there are multiple instances of that object in the tree and the user does not have to worry about memory cleanup. shared_ptr<nowiki><XdmfDomain></nowiki> root = XdmfDomain::New(); # Information shared_ptr<nowiki><XdmfInformation></nowiki> i = XdmfInformation::New(); # Arbitrary Name=Value Facility i->setName("Time"); i->setValue(0.0123); root->insert(i); # XdmfDomain is the root of the tree # insert adds the information we just created as a leaf # Dimensions shared_ptr<nowiki><XdmfArray></nowiki> dimensions = XdmfArray::New(); dimensions->pushBack((unsigned int)10); dimensions->pushBack((unsigned int)20); dimensions->pushBack((unsigned int)30); # Origin shared_ptr<nowiki><XdmfArray></nowiki> origin = XdmfArray::New(); origin->pushBack((unsigned int)1); origin->pushBack((unsigned int)2); origin->pushBack((unsigned int)3); # Brick Size shared_ptr<nowiki><XdmfArray></nowiki> brick = XdmfArray::New(); brick->pushBack((unsigned int)1); brick->pushBack((unsigned int)2); brick->pushBack((unsigned int)3); # Grid shared_ptr<nowiki><XdmfRegularGrid></nowiki> g = XdmfRegularGrid::New(brick, dimensions, origin); g->setName("Structured Grid"); root->insert(g); # Attribute shared_ptr<nowiki><XdmfAttribute></nowiki> attr = XdmfAttribute::New(); attr->setName("Pressure"); attr->setAttributeCenter(XdmfAttributeCenter::Cell()); attr->setAttributeType(XdmfAttributeType::Scalar()); attr->initialize(XdmfArrayType::Float64(), 10 * 20 * 30); double * pressureVals = [0, 1, 2, 3, 4, 5, ...]; attr->insert(0, pressureVals, numPressureVals); # The heavy data set name is determined by the writer if not set g->insert(attr); # Generate a writer shared_ptr<nowiki><XdmfWriter></nowiki> writer = XdmfWriter::New(<nowiki>"output.xmf"</nowiki>); domain->accept(writer) e2c545132bd712573af50374d355a805a8add5e5 Xdmf3 Fortran API 0 25 135 2014-11-07T18:44:32Z Burns 17 Created page with "[[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a..." wikitext text/x-wiki [[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root. After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain. CALL XDMFINIT(obj, filename) The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root. ===XdmfGridCollections=== After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to. Xdmf API Grid Collection Stack: Domain <-- top of stack Add a Grid Collection to the tree: ! Adding a Grid Collection named "Grid Collection" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Another Grid Collection is added: ! Adding a Grid Collection named "Grid Collection2" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION. Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Remove a Grid Collection from the top of the stack: CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Returning a Grid Collection to the stack adds it to the top: ! Returning the Grid Collection contained in the domain at position 0 to the stack CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added. Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls. CALL XDMFINIT(obj, filename) Xdmf API Grid Collection Stack: Domain <-- top of stack Xdmf Tree: Domain ! Adding a Grid Collection named "Grid Collection" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Xdmf Tree: Domain |->Grid Collection ! Adding a Grid Collection named "Grid Collection2" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Xdmf Tree Domain |->Grid Collection |->Grid Collection2 ! Removing the grid Collection from the top of the stack. CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 ! Adding a Grid Collection named "Grid Collection3" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 ed399955b666d38ddb9e9f74c89094b93cd882e9 136 135 2014-11-07T19:15:06Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root. After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain. CALL XDMFINIT(obj, filename) The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root. ===XdmfGridCollections=== After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to. Xdmf API Grid Collection Stack: Domain <-- top of stack Add a Grid Collection to the tree: ! Adding a Grid Collection named "Grid Collection" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Another Grid Collection is added: ! Adding a Grid Collection named "Grid Collection2" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION. Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Remove a Grid Collection from the top of the stack: CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Returning a Grid Collection to the stack adds it to the top: ! Returning the Grid Collection contained in the domain at position 0 to the stack CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added. Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls. CALL XDMFINIT(obj, filename) Xdmf API Grid Collection Stack: Domain <-- top of stack Xdmf Tree: Domain ! Adding a Grid Collection named "Grid Collection" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Xdmf Tree: Domain |->Grid Collection ! Adding a Grid Collection named "Grid Collection2" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Xdmf Tree Domain |->Grid Collection |->Grid Collection2 ! Removing the grid Collection from the top of the stack. CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 ! Adding a Grid Collection named "Grid Collection3" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 When generating Attributes, Information, Maps, and Sets the created items are simultaniously added to a work array and an archive array. Creating certain objects clears certain working arrays after adding the items contained within. {| class="wikitable" !Object !Working Arrays Cleared |- |GridCollection |Attributes, Information, Maps, Sets |- |Grid |Attributes, Information, Maps, Sets |- |Attribute |Information |- |Information |None |- |Map |none |- |Set |Attributes, Information |} After an item is cleared from a working array, it can be added back either by calling the appropriate OPEN command or by adding it via its index in the archive array using the appropriate version of AddPrevious. The index of an object in the archive array is what is returned by the Add function when it is called. ! Adding an attribute that is named "Attribute 1" ! Centered on Node ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 1'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |} Xdmf Tree: Attribute 1 ! Adding an information named "Information 1" tempID = XDMFADDINFORMATION(obj, 'Information 1'//CHAR(0), 'This is Information 1'//CHAR(0)) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |} {| class="wikitable" !Information Working !Information Archive |- |Information 1 |Information 1 |} Xdmf Tree: Attribute 1 Information 1 ! Adding an attribute that is named "Attribute 2" ! Centered on Nodex ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 2'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |- |Attribute 2 |Attribute 2 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |} Xdmf Tree: Attribute 1 Attribute 2 |->Information 1 ! Adding a set that is named "Set 1" ! A set of Node Type ! contains 12 float values loaded from myNodeAttribute testSetID = XDMFADDSET(obj, 'Set 1'//CHAR(0), XDMF_SET_TYPE_NODE, & myNodeAttribute, 12, XDMF_ARRAY_TYPE_FLOAT64) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 ! Adding an attribute that is named "Attribute 3" ! Centered on Node ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 3'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) ! Adding an Information named "Information 2" tempID = XDMFADDINFORMATION(obj, 'Information 2'//CHAR(0), 'This is Information 2'//CHAR(0)) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 3 |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- |Information 2 |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 Attribute 3 Information 2 ! Adding a grid named "Unstructured Grid" CALL XDMFADDGRID(obj, 'Unstructured Grid'//CHAR(0), .FALSE.) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- | |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 If we wanted to add another grid with the same internal objects we would call the appropriate add previous methods to add them back into the working arrays. ! Note: Using hard coded indecies here ! the return value from any of the add functions ! such as XdmfAddInformation may also be used CALL XDMFADDPREVIOUSATTRIBUTE(obj, 3) CALL XDMFADDPREVIOUSINFORMATION(obj, 2) CALL XDMFADDPREVIOUSSET(obj, 1) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 3 |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- |Information 2 |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 Attribute 3 Information 2 Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 Then we simply call add grid again to insert a grid with the current contents of the working arrays ! Adding a grid named "Unstructured Grid 2" CALL XDMFADDGRID(obj, 'Unstructured Grid 2'//CHAR(0), .FALSE.) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- | |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 |->Unstructured Grid 2 |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 75d9e8256e26aeb3caaadb3953cae0a11fe91701 137 136 2014-11-07T19:19:08Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root. After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain. CALL XDMFINIT(obj, filename) The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root. ===XdmfGridCollections=== After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to. Xdmf API Grid Collection Stack: Domain <-- top of stack Add a Grid Collection to the tree: ! Adding a Grid Collection named "Grid Collection" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Another Grid Collection is added: ! Adding a Grid Collection named "Grid Collection2" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION. Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Remove a Grid Collection from the top of the stack: CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Returning a Grid Collection to the stack adds it to the top: ! Returning the Grid Collection contained in the domain at position 0 to the stack CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added. Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls. CALL XDMFINIT(obj, filename) Xdmf API Grid Collection Stack: Domain <-- top of stack Xdmf Tree: Domain ! Adding a Grid Collection named "Grid Collection" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Xdmf Tree: Domain |->Grid Collection ! Adding a Grid Collection named "Grid Collection2" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Xdmf Tree Domain |->Grid Collection |->Grid Collection2 ! Removing the grid Collection from the top of the stack. CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 ! Adding a Grid Collection named "Grid Collection3" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 ===Xdmf Arrays and other Data=== ====Adding Data to Grids==== When generating Attributes, Information, Maps, and Sets the created items are simultaniously added to a work array and an archive array. Creating certain objects clears certain working arrays after adding the items contained within. {| class="wikitable" !Object !Working Arrays Cleared |- |GridCollection |Attributes, Information, Maps, Sets |- |Grid |Attributes, Information, Maps, Sets |- |Attribute |Information |- |Information |None |- |Map |none |- |Set |Attributes, Information |} ====Retrieving Data from Closed Grids==== After an item is cleared from a working array, it can be added back either by calling the appropriate OPEN command or by adding it via its index in the archive array using the appropriate version of AddPrevious. The index of an object in the archive array is what is returned by the Add function when it is called. ! Adding an attribute that is named "Attribute 1" ! Centered on Node ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 1'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |} Xdmf Tree: Attribute 1 ! Adding an information named "Information 1" tempID = XDMFADDINFORMATION(obj, 'Information 1'//CHAR(0), 'This is Information 1'//CHAR(0)) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |} {| class="wikitable" !Information Working !Information Archive |- |Information 1 |Information 1 |} Xdmf Tree: Attribute 1 Information 1 ! Adding an attribute that is named "Attribute 2" ! Centered on Nodex ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 2'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |- |Attribute 2 |Attribute 2 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |} Xdmf Tree: Attribute 1 Attribute 2 |->Information 1 ! Adding a set that is named "Set 1" ! A set of Node Type ! contains 12 float values loaded from myNodeAttribute testSetID = XDMFADDSET(obj, 'Set 1'//CHAR(0), XDMF_SET_TYPE_NODE, & myNodeAttribute, 12, XDMF_ARRAY_TYPE_FLOAT64) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 ! Adding an attribute that is named "Attribute 3" ! Centered on Node ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 3'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) ! Adding an Information named "Information 2" tempID = XDMFADDINFORMATION(obj, 'Information 2'//CHAR(0), 'This is Information 2'//CHAR(0)) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 3 |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- |Information 2 |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 Attribute 3 Information 2 ! Adding a grid named "Unstructured Grid" CALL XDMFADDGRID(obj, 'Unstructured Grid'//CHAR(0), .FALSE.) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- | |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 ====Adding Previously Created Datasets==== If we wanted to add another grid with the same internal objects we would call the appropriate add previous methods to add them back into the working arrays. ! Note: Using hard coded indecies here ! the return value from any of the add functions ! such as XdmfAddInformation may also be used CALL XDMFADDPREVIOUSATTRIBUTE(obj, 3) CALL XDMFADDPREVIOUSINFORMATION(obj, 2) CALL XDMFADDPREVIOUSSET(obj, 1) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 3 |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- |Information 2 |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 Attribute 3 Information 2 Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 Then we simply call add grid again to insert a grid with the current contents of the working arrays ! Adding a grid named "Unstructured Grid 2" CALL XDMFADDGRID(obj, 'Unstructured Grid 2'//CHAR(0), .FALSE.) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- | |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 |->Unstructured Grid 2 |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 f7b4907aaa10bfabf196d31740bd7c6e75418091 138 137 2014-11-07T19:58:29Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] __TOC__ ==XDMF API== The Fortran interface for Xdmf has a vastly different workflow from the C++ API. The C++ API workflow starts from the root of a tree and builds up to the leaves. The workflow for XdmfFortran starts at the leaves and collapses down to the root. After including Xdmf.f, the first thing that needs to occur is a call to XDMFINIT in order to set up the base root of the Xdmf tree, an object of the type XdmfDomain. CALL XDMFINIT(obj, filename) The location of the interface object is stored in obj. This obj variable is then passed to most calls to the Xdmf Interface to interact with the root and the objects that are being generated to be added to the root. ===XdmfGridCollections=== After setting up the base root, any grid collections added using XDMFADDGRIDCOLLECTION are added to the current root. After being added to the root, the grid collection is placed on top of the stack and take the place of the root they were added to. Xdmf API Grid Collection Stack: Domain <-- top of stack Add a Grid Collection to the tree: ! Adding a Grid Collection named "Grid Collection" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Another Grid Collection is added: ! Adding a Grid Collection named "Grid Collection2" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Calling XDMFCLOSEGRIDCOLLECTION removes a grid collection from the top of the stack. It is still connected to the grid collection below it (what is at the top of the stack after the call) and may be added back to the top of the stack using XDMFOPENDOMAINGRIDCOLLECTION. Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Remove a Grid Collection from the top of the stack: CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Returning a Grid Collection to the stack adds it to the top: ! Returning the Grid Collection contained in the domain at position 0 to the stack CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain In order to add multiple grid collections to the same root XDMFCLOSEGRIDCOLLECTION must be called to remove the child from the stack before the new grid collection can be added. Xdmf Tree represents the underlying Xml tree and c++ object structure created by the calls. CALL XDMFINIT(obj, filename) Xdmf API Grid Collection Stack: Domain <-- top of stack Xdmf Tree: Domain ! Adding a Grid Collection named "Grid Collection" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Xdmf Tree: Domain |->Grid Collection ! Adding a Grid Collection named "Grid Collection2" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection2"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection2 <-- top of stack Grid Collection Domain Xdmf Tree Domain |->Grid Collection |->Grid Collection2 ! Removing the grid Collection from the top of the stack. CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.) Xdmf API Grid Collection Stack: Grid Collection <-- top of stack Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 ! Adding a Grid Collection named "Grid Collection3" CALL XDMFADDGRIDCOLLECTION(obj, "Grid Collection3"//CHAR(0), & XDMF_GRID_COLLECTION_TYPE_TEMPORAL) Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 ===Xdmf Arrays and other Data=== ====Adding Data to Grids==== When generating Attributes, Information, Maps, and Sets the created items are simultaniously added to a work array and an archive array. Creating certain objects clears certain working arrays after adding the items contained within. {| class="wikitable" !Object !Working Arrays Cleared |- |GridCollection |Attributes, Information, Maps, Sets |- |Grid |Attributes, Information, Maps, Sets |- |Attribute |Information |- |Information |None |- |Map |none |- |Set |Attributes, Information |} ====Retrieving Data from Closed Grids==== After an item is cleared from a working array, it can be added back either by calling the appropriate OPEN command or by adding it via its index in the archive array using the appropriate version of AddPrevious. The index of an object in the archive array is what is returned by the Add function when it is called. ! Adding an attribute that is named "Attribute 1" ! Centered on Node ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 1'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |} Xdmf Tree: Attribute 1 ! Adding an information named "Information 1" tempID = XDMFADDINFORMATION(obj, 'Information 1'//CHAR(0), 'This is Information 1'//CHAR(0)) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |} {| class="wikitable" !Information Working !Information Archive |- |Information 1 |Information 1 |} Xdmf Tree: Attribute 1 Information 1 ! Adding an attribute that is named "Attribute 2" ! Centered on Nodex ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 2'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 1 |Attribute 1 |- |Attribute 2 |Attribute 2 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |} Xdmf Tree: Attribute 1 Attribute 2 |->Information 1 ! Adding a set that is named "Set 1" ! A set of Node Type ! contains 12 float values loaded from myNodeAttribute testSetID = XDMFADDSET(obj, 'Set 1'//CHAR(0), XDMF_SET_TYPE_NODE, & myNodeAttribute, 12, XDMF_ARRAY_TYPE_FLOAT64) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 ! Adding an attribute that is named "Attribute 3" ! Centered on Node ! Scalar type ! contains 12 float values loaded from myNodeAttribute nodeAttributeId = XDMFADDATTRIBUTE(obj, 'Attribute 3'//CHAR(0), & XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, & XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute) ! Adding an Information named "Information 2" tempID = XDMFADDINFORMATION(obj, 'Information 2'//CHAR(0), 'This is Information 2'//CHAR(0)) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 3 |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- |Information 2 |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 Attribute 3 Information 2 ! Adding a grid named "Unstructured Grid" CALL XDMFADDGRID(obj, 'Unstructured Grid'//CHAR(0), .FALSE.) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- | |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 ====Adding Previously Created Datasets==== If we wanted to add another grid with the same internal objects we would call the appropriate add previous methods to add them back into the working arrays. ! Note: Using hard coded indecies here ! the return value from any of the add functions ! such as XdmfAddInformation may also be used CALL XDMFADDPREVIOUSATTRIBUTE(obj, 3) CALL XDMFADDPREVIOUSINFORMATION(obj, 2) CALL XDMFADDPREVIOUSSET(obj, 1) {| class="wikitable" !Attribute Working !Attribute Archive |- |Attribute 3 |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- |Information 2 |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- |Set 1 |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 Attribute 3 Information 2 Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 Then we simply call add grid again to insert a grid with the current contents of the working arrays ! Adding a grid named "Unstructured Grid 2" CALL XDMFADDGRID(obj, 'Unstructured Grid 2'//CHAR(0), .FALSE.) {| class="wikitable" !Attribute Working !Attribute Archive |- | |Attribute 1 |- | |Attribute 2 |- | |Attribute 3 |} {| class="wikitable" !Information Working !Information Archive |- | |Information 1 |- | |Information 2 |} {| class="wikitable" !Set Working !Set Archive |- | |Set 1 |} Xdmf API Grid Collection Stack: Grid Collection3 <-- top of stack Grid Collection Domain Xdmf Tree: Domain |->Grid Collection |->Grid Collection2 |->Grid Collection3 |->Unstructured Grid |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 |->Unstructured Grid 2 |->Set 1 |->Attribute 1 |->Attribute 2 |->Information 1 |->Attribute 3 |->Information 2 ===Writing to File=== After using the above steps to construct the desired data structure, the structure can be written to file. CALL XDMFWRITEHDF5(obj, 'my_output.h5'//CHAR(0), .TRUE.) CALL XDMFWRITE(obj, 'my_output.xmf'//CHAR(0), 10, .TRUE.) Then the XdmfFortran API should be closed. CALL XDMFCLOSE(obj) ===Reading from File=== The following call will read an Xdmf structure from a file and set the API's domain to the domain that was read from the file. CALL XDMFREAD(obj, 'my_output.xmf'//CHAR(0)) ===Retrieving Data from the Xdmf Structure=== ====Opening Items==== When a Domain has been read from file no data is yet accessable. First the user needs to open the grids that the Domain contains. Each object has a corresponding XDMFOPEN call, using an Unstructured Grid as an example: CALL XDMFOPENGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 1, 1, 1, 1) This call will open the unstructured grid at index 0 from the grid collection currently at the top of the stack. The Maps, Attributes, Information, and Sets of that grid will be placed in the appropriate working arrays based on the last four values passed accordingly. This example opens all of them. ====Retrieving/Modifying Data from Arrays==== When an array such as an Attribute is loaded into the working array, its attributes can be interacted with. XdmfRetrieveNumAttributes will produce the number of attributes currently loaded, which can then be referenced by index. CALL XDMFRETRIEVENUMATTRIBUTES(obj, numContained) PRINT *, 'Number of Grid Attributes: ', numContained An Attribute's data can be retrieved like so: CHARACTER*256 itemName, itemKey, itemValue, itemTag INTEGER numContained, typeHolder REAL*8 myNodeAttributeOutput(12) CALL XDMFRETRIEVEATTRIBUTENAME(obj, 0, itemName, 256) PRINT *, 'Attribute Name: ', itemName CALL XDMFRETRIEVEATTRIBUTENUMPROPERTIES(obj, 0, numContained) PRINT *, "Number of Properties: ", numContained CALL XDMFRETRIEVEATTRIBUTEPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256) PRINT *, "Key: ", itemKey PRINT *, "Value: ", itemValue CALL XDMFRETRIEVEATTRIBUTEPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256) PRINT *, "Value: ", itemValue CALL XDMFRETRIEVEATTRIBUTETAG(obj, 0, itemTag, 256) PRINT *, 'Attribute Tag: ', itemTag CALL XDMFRETRIEVEATTRIBUTETYPE(obj, 0, typeHolder) PRINT *, 'Attribute Type: ', typeHolder CALL XDMFRETRIEVEATTRIBUTECENTER(obj, 0, typeHolder) PRINT *, 'Attribute Center: ', typeHolder CALL XDMFRETRIEVEATTRIBUTEVALUETYPE(obj, 0, typeHolder) PRINT *, 'Attribute Value Type: ', typeHolder CALL XDMFRETRIEVEATTRIBUTESIZE(obj, 0, numContained) PRINT *, 'Number of Values: ', numContained CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 0, myNodeAttributeOutput, XDMF_ARRAY_TYPE_FLOAT64, 12, 0, 1, 1) PRINT 3, myNodeAttributeOutput 3 FORMAT (' ', 3F6.1) If you wanted to modify an Attribute's array instead of retrieve it. CALL XDMFMODIFYATTRIBUTEVALUES(obj, & startIndex, & myNodeAttributeVals, & XDMF_ARRAY_TYPE_FLOAT64, & numVals, & valueStartIndex, & 1, & 1) e5666a422e3a05aa03615b406a5c312d709112f6 XDMF Model and Format 0 2 139 94 2014-11-07T20:00:41Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 3231041628019305600647b563bc68b6f4c0929d Xdmf2 Model and Format Archive 0 26 140 2014-11-07T20:00:55Z Burns 17 Created page with "[[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXt..." wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") dbfc6f7c2523db7dc46fae5158a538785450a26e 141 140 2014-11-07T20:36:16Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Subset''' - A variation of what was originally Hyperslab in Xdmf2. The Attributes of the tag specify a selection over the child array. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Subset''' A ''Subset'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. <nowiki><Subset ConstructedType="DataItem" </nowiki> DataType="UInt" Dimensions="8" Format="XML" Precision="4" SubsetDimensions="2 2 2" SubsetStarts="0 0 0" <nowiki>SubsetStrides="2 2 2"></nowiki> <nowiki><DataItem DataType="Int"</nowiki> Dimensions="1" Format="XML" <nowiki>Precision="4"></nowiki> 0 <nowiki></DataItem></nowiki> <nowiki><DataItem DataType="UInt"</nowiki> Dimensions="3 3 3" Format="XML" <nowiki>Precision="4"></nowiki> 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <nowiki</DataItem></nowiki> <nowiki></Subset></nowiki> The first DataItem child is what the subset is initially set to before its associated heavy data is read in. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The children ar assigned variables based on the VariableNames attribute. The first child is what the function is initialized to before reading in the operation thus it is not assigned a variable. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A+B" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="XML" <nowiki>Precision="4"></nowiki> 1.0 2.0 3.0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="XML" <nowiki>Precision="4"></nowiki> 4.1 5.2 6.3 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> The ConstructedType attribute allows function to produce Geometries and Topologies in addtion to standard Arrays. It inherits the attributes of the array subtype that it would produce. The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. It allows for the old concatenate JOIN in addition to the following operators: -,+,/,*,|(concatenate),#(interlace) Add the value 10 to every element <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="10+A" Format="XML" Precision="4" <nowiki>VariableNames="|A"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Multiply two arrays (element by element) and take the absolute value <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="ABS(A*B)" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Concatenate two arrays <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A|B" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Interlace 3 arrays (Useful for describing vectors from scalar data) <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A#B#C" Format="XML" Precision="4" <nowiki>VariableNames="|A|B|C"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data2 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") add849725360d8f5325400e7ea4dfa0557f03051 142 141 2014-11-07T21:04:34Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Subset''' - A variation of what was originally Hyperslab in Xdmf2. The Attributes of the tag specify a selection over the child array. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Subset''' A ''Subset'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. <nowiki><Subset ConstructedType="DataItem" </nowiki> DataType="UInt" Dimensions="8" Format="XML" Precision="4" SubsetDimensions="2 2 2" SubsetStarts="0 0 0" <nowiki>SubsetStrides="2 2 2"></nowiki> <nowiki><DataItem DataType="Int"</nowiki> Dimensions="1" Format="XML" <nowiki>Precision="4"></nowiki> 0 <nowiki></DataItem></nowiki> <nowiki><DataItem DataType="UInt"</nowiki> Dimensions="3 3 3" Format="XML" <nowiki>Precision="4"></nowiki> 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <nowiki</DataItem></nowiki> <nowiki></Subset></nowiki> The first DataItem child is what the subset is initially set to before its associated heavy data is read in. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The children ar assigned variables based on the VariableNames attribute. The first child is what the function is initialized to before reading in the operation thus it is not assigned a variable. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A+B" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="XML" <nowiki>Precision="4"></nowiki> 1.0 2.0 3.0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="XML" <nowiki>Precision="4"></nowiki> 4.1 5.2 6.3 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> The ConstructedType attribute allows function to produce Geometries and Topologies in addtion to standard Arrays. It inherits the attributes of the array subtype that it would produce. The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. It allows for the old concatenate JOIN in addition to the following operators: -,+,/,*,|(concatenate),#(interlace) Add the value 10 to every element <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="10+A" Format="XML" Precision="4" <nowiki>VariableNames="|A"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Multiply two arrays (element by element) and take the absolute value <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="ABS(A*B)" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Concatenate two arrays <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A|B" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Interlace 3 arrays (Useful for describing vectors from scalar data) <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A#B#C" Format="XML" Precision="4" <nowiki>VariableNames="|A|B|C"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data2 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> The old Xdmf2 style of functions is still supported in most cases. '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. A Grid can also consist of a collection of child grids arranged either temporally or spatially. This is known as a Grid Collection and is specified by setting the GridType attribute to "Collection" <nowiki><Grid</nowiki> CollectionType="Spatial" GridType="Collection" <nowiki>Name="Collection"></nowiki> <nowiki><Grid Name="Grid0"></nowiki> <nowiki><Geometry Origin="" Type="ORIGIN_DXDYDZ"></nowiki> <nowiki><DataItem</nowiki> DataType="Float" Dimensions="3" Format="XML" <nowiki>Precision="8"></nowiki> 1 1 0 <nowiki></DataItem></nowiki> <nowiki><DataItem</nowiki> DataType="Float" Dimensions="3" Format="XML" <nowiki>Precision="8"></nowiki> 1 1 1 <nowiki></DataItem></nowiki> <nowiki></Geometry></nowiki> <nowiki><Topology Dimensions="10 10 10" Type="3DCoRectMesh"/></nowiki> <nowiki></Grid></nowiki> <nowiki><Grid Name="Grid1"></nowiki> <nowiki><Geometry Origin="" Type="ORIGIN_DXDYDZ"></nowiki> <nowiki><DataItem</nowiki> DataType="Float" Dimensions="3" Format="XML" <nowiki>Precision="8"></nowiki> 1 1 1 <nowiki></DataItem></nowiki> <nowiki><DataItem</nowiki> DataType="Float" Dimensions="3" Format="XML" <nowiki>Precision="8"></nowiki> 1 1 1 <nowiki></DataItem></nowiki> <nowiki></Geometry></nowiki> <nowiki><Topology Dimensions="10 10 10" Type="3DCoRectMesh"/></nowiki> <nowiki></Grid></nowiki> <nowiki></Grid></nowiki> '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. It contains a single floating point value. So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Subset (XdmfSubset) As Parent and: SubsetDimensions (no default) in KJI Order SubsetStarts (no default) in KJI Order SubsetStrides (no default) in KJI Order * Function (XdmfFunction) As Parent and: Expression (no default) VariableName "|" (no variables specified) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 5e689c4dcaf0fa3bd203ea5a0b625b4b60dc709b 143 142 2014-11-07T21:05:27Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Subset''' - A variation of what was originally Hyperslab in Xdmf2. The Attributes of the tag specify a selection over the child array. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Subset''' A ''Subset'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. <nowiki><Subset ConstructedType="DataItem" </nowiki> DataType="UInt" Dimensions="8" Format="XML" Precision="4" SubsetDimensions="2 2 2" SubsetStarts="0 0 0" <nowiki>SubsetStrides="2 2 2"></nowiki> <nowiki><DataItem DataType="Int"</nowiki> Dimensions="1" Format="XML" <nowiki>Precision="4"></nowiki> 0 <nowiki></DataItem></nowiki> <nowiki><DataItem DataType="UInt"</nowiki> Dimensions="3 3 3" Format="XML" <nowiki>Precision="4"></nowiki> 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <nowiki</DataItem></nowiki> <nowiki></Subset></nowiki> The first DataItem child is what the subset is initially set to before its associated heavy data is read in. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The children ar assigned variables based on the VariableNames attribute. The first child is what the function is initialized to before reading in the operation thus it is not assigned a variable. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A+B" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="XML" <nowiki>Precision="4"></nowiki> 1.0 2.0 3.0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="XML" <nowiki>Precision="4"></nowiki> 4.1 5.2 6.3 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> The ConstructedType attribute allows function to produce Geometries and Topologies in addtion to standard Arrays. It inherits the attributes of the array subtype that it would produce. The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. It allows for the old concatenate JOIN in addition to the following operators: -,+,/,*,|(concatenate),#(interlace) Add the value 10 to every element <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="10+A" Format="XML" Precision="4" <nowiki>VariableNames="|A"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Multiply two arrays (element by element) and take the absolute value <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="ABS(A*B)" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Concatenate two arrays <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A|B" Format="XML" Precision="4" <nowiki>VariableNames="|A|B"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> Interlace 3 arrays (Useful for describing vectors from scalar data) <nowiki><Function</nowiki> ConstructedType="DataItem" DataType="Float" Dimensions="3" Expression="A#B#C" Format="XML" Precision="4" <nowiki>VariableNames="|A|B|C"></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data0 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data1 <nowiki></DataItem></nowiki> <nowiki><DataItem Dimensions="3"</nowiki> DataType="Float" Format="HDF" <nowiki>Precision="4"></nowiki> data.h5:Data2 <nowiki></DataItem></nowiki> <nowiki></DataItem></nowiki> The old Xdmf2 style of functions is still supported in most cases. '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. A Grid can also consist of a collection of child grids arranged either temporally or spatially. This is known as a Grid Collection and is specified by setting the GridType attribute to "Collection" <nowiki><Grid</nowiki> CollectionType="Spatial" GridType="Collection" <nowiki>Name="Collection"></nowiki> <nowiki><Grid Name="Grid0"></nowiki> <nowiki><Geometry Origin="" Type="ORIGIN_DXDYDZ"></nowiki> <nowiki><DataItem</nowiki> DataType="Float" Dimensions="3" Format="XML" <nowiki>Precision="8"></nowiki> 1 1 0 <nowiki></DataItem></nowiki> <nowiki><DataItem</nowiki> DataType="Float" Dimensions="3" Format="XML" <nowiki>Precision="8"></nowiki> 1 1 1 <nowiki></DataItem></nowiki> <nowiki></Geometry></nowiki> <nowiki><Topology Dimensions="10 10 10" Type="3DCoRectMesh"/></nowiki> <nowiki></Grid></nowiki> <nowiki><Grid Name="Grid1"></nowiki> <nowiki><Geometry Origin="" Type="ORIGIN_DXDYDZ"></nowiki> <nowiki><DataItem</nowiki> DataType="Float" Dimensions="3" Format="XML" <nowiki>Precision="8"></nowiki> 1 1 1 <nowiki></DataItem></nowiki> <nowiki><DataItem</nowiki> DataType="Float" Dimensions="3" Format="XML" <nowiki>Precision="8"></nowiki> 1 1 1 <nowiki></DataItem></nowiki> <nowiki></Geometry></nowiki> <nowiki><Topology Dimensions="10 10 10" Type="3DCoRectMesh"/></nowiki> <nowiki></Grid></nowiki> <nowiki></Grid></nowiki> '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. It contains a single floating point value. So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Subset (XdmfSubset) As Parent and: SubsetDimensions (no default) in KJI Order SubsetStarts (no default) in KJI Order SubsetStrides (no default) in KJI Order * Function (XdmfFunction) As Parent and: Expression (no default) VariableName "|" (no variables specified) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time Value (no default - Only valid for TimeType="Single") 27a2f89d8e3a0dd674dab4513ecd79211bcca810 User:Dhuckaby 2 27 151 2015-01-12T15:08:11Z Dave.demarle 5 Creating user page for new user. wikitext text/x-wiki Mechanical Engineer National Energy Technology Laboratory 18d059e7638cfaedf741784596e66f3fa8445a6e User talk:Dhuckaby 3 28 152 2015-01-12T15:08:11Z Dave.demarle 5 Welcome! wikitext text/x-wiki '''Welcome to ''XdmfWeb''!''' We hope you will contribute much and well. You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages]. Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 10:08, 12 January 2015 (EST) e0d91444b4220252d6b1a6b8dbde7b5dd89376f7 V3 Road Feature Request 0 15 153 95 2015-01-12T20:06:59Z Dhuckaby 20 /* Version 3 Feature Request' */ wikitext text/x-wiki == Version 3 Feature Request' == '''Implement AttributeType=Matrix''' I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example on how to use the Matrix AttributeMatrix. For example I have a triangular surface mesh where each triangle has a (2x1) matrix of values so that each triangle has 2 values. Currently we have to setup a hyper slab for the data array and end up with 2 data items. <Attribute Name="SurfaceMeshFaceLabels (Feature 0)" AttributeType="Scalar" Center="Cell"> <DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 0)" > <DataItem Dimensions="3 2" Format="XML" > 0 0 1 1 757136 1 </DataItem> <DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" > Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </DataItem> </Attribute> <Attribute Name="SurfaceMeshFaceLabels (Feature 1)" AttributeType="Scalar" Center="Cell"> <DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 1)" > <DataItem Dimensions="3 2" Format="XML" > 0 1 1 1 757136 1 </DataItem> <DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" > Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </DataItem> </Attribute> I would rather do something like this: <Attribute Center="Cell" Name="Phases_Matrix" Type="Matrix"> <DataItem Dimensions="2 1" Format="XML" >2 1</DataItem> <DataItem DataType="Int" Dimensions="757136 2" Format="HDF" Precision="4"> Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </Attribute> Or something like that. '''1DCoRectMesh''' I will like to have also something like 1DCORECTMesh, for the moment I Use a 2DCORECTMesh with only 1 point in the second direction. But cant be used with cell data (paraview crash). So I use only point data. '''Polyhedral Cells''' It would be great to have the XDMF specification and library support polyhedral cells http://public.kitware.com/Bug/view.php?id=14528 4efb61b19e3656219a262b91e7d2aee15a8ae866 154 153 2015-01-12T20:07:43Z Dhuckaby 20 /* Version 3 Feature Request' */ wikitext text/x-wiki == Version 3 Feature Request' == '''Implement AttributeType=Matrix''' I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example on how to use the Matrix AttributeMatrix. For example I have a triangular surface mesh where each triangle has a (2x1) matrix of values so that each triangle has 2 values. Currently we have to setup a hyper slab for the data array and end up with 2 data items. <Attribute Name="SurfaceMeshFaceLabels (Feature 0)" AttributeType="Scalar" Center="Cell"> <DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 0)" > <DataItem Dimensions="3 2" Format="XML" > 0 0 1 1 757136 1 </DataItem> <DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" > Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </DataItem> </Attribute> <Attribute Name="SurfaceMeshFaceLabels (Feature 1)" AttributeType="Scalar" Center="Cell"> <DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 1)" > <DataItem Dimensions="3 2" Format="XML" > 0 1 1 1 757136 1 </DataItem> <DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" > Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </DataItem> </Attribute> I would rather do something like this: <Attribute Center="Cell" Name="Phases_Matrix" Type="Matrix"> <DataItem Dimensions="2 1" Format="XML" >2 1</DataItem> <DataItem DataType="Int" Dimensions="757136 2" Format="HDF" Precision="4"> Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </Attribute> Or something like that. '''1DCoRectMesh''' I will like to have also something like 1DCORECTMesh, for the moment I Use a 2DCORECTMesh with only 1 point in the second direction. But cant be used with cell data (paraview crash). So I use only point data. '''Polyhedral Cells''' It would be great to have the XDMF specification and library support polyhedral cells http://public.kitware.com/Bug/view.php?id=14528 a47212f48577a83e321b0093d1d77a90e03a42f4 157 154 2015-04-17T15:19:37Z Chrisr 21 /* Version 3 Feature Request' */ wikitext text/x-wiki == Version 3 Feature Request' == '''Implement AttributeType=Matrix''' I would like to see the Matrix type implemented so that ParaView can open the files. A clear Example on how to use the Matrix AttributeMatrix. For example I have a triangular surface mesh where each triangle has a (2x1) matrix of values so that each triangle has 2 values. Currently we have to setup a hyper slab for the data array and end up with 2 data items. <Attribute Name="SurfaceMeshFaceLabels (Feature 0)" AttributeType="Scalar" Center="Cell"> <DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 0)" > <DataItem Dimensions="3 2" Format="XML" > 0 0 1 1 757136 1 </DataItem> <DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" > Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </DataItem> </Attribute> <Attribute Name="SurfaceMeshFaceLabels (Feature 1)" AttributeType="Scalar" Center="Cell"> <DataItem ItemType="HyperSlab" Dimensions="757136 1" Type="HyperSlab" Name="SurfaceMeshFaceLabels (Feature 1)" > <DataItem Dimensions="3 2" Format="XML" > 0 1 1 1 757136 1 </DataItem> <DataItem Format="HDF" Dimensions="757136 2" NumberType="Int" Precision="4" > Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </DataItem> </Attribute> I would rather do something like this: <Attribute Center="Cell" Name="Phases_Matrix" Type="Matrix"> <DataItem Dimensions="2 1" Format="XML" >2 1</DataItem> <DataItem DataType="Int" Dimensions="757136 2" Format="HDF" Precision="4"> Matrix_XDMF_Test.dream3d:/DataContainers/SurfaceDataContainer/FaceData/SurfaceMeshFaceLabels </DataItem> </Attribute> Or something like that. '''1DCoRectMesh''' I will like to have also something like 1DCORECTMesh, for the moment I Use a 2DCORECTMesh with only 1 point in the second direction. But cant be used with cell data (paraview crash). So I use only point data. '''Polyhedral Cells''' It would be great to have the XDMF specification and library support polyhedral cells http://public.kitware.com/Bug/view.php?id=14528 '''Set''' Already implemented (unofficially?) by VTK [https://github.com/Kitware/VTK/blob/master/ThirdParty/xdmf2/vtkxdmf2/libsrc/XdmfSet.h XdmfSet.h], this is pretty similar to the '''GridType="Subset"'''. This would be useful for specifying boundary conditions on models. However, it needs a clearer definition of how to access Edges and Faces in 2D and 3D. e.g. they could be identified by CellId and then the cell-local FaceId/EdgeId? 93bce9282d68afb658c1590d5c8ca8321c5da2da User:Chrisr 2 29 155 2015-04-17T13:43:29Z Dave.demarle 5 Creating user page for new user. wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 User talk:Chrisr 3 30 156 2015-04-17T13:43:30Z Dave.demarle 5 Welcome! wikitext text/x-wiki '''Welcome to ''XdmfWeb''!''' We hope you will contribute much and well. You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages]. Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 09:43, 17 April 2015 (EDT) 3d30d8097abf7a766f922adeddcb6f9e41890ab9 User:Milanberjan 2 31 158 2015-05-01T14:05:35Z Dave.demarle 5 Creating user page for new user. wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 User talk:Milanberjan 3 32 159 2015-05-01T14:05:36Z Dave.demarle 5 Welcome! wikitext text/x-wiki '''Welcome to ''XdmfWeb''!''' We hope you will contribute much and well. You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages]. Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 10:05, 1 May 2015 (EDT) e6d8564afa5e700a0088b8c2d109cea268cfbec2 XDMF Model and Format 0 2 160 139 2015-06-01T09:38:30Z Chrisr 21 Update description of Edge and Face based attributes wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") c5f69aeabddd2f0d9f1186f558a81623006715ff 161 160 2015-06-01T10:29:09Z Chrisr 21 Add definition of <Set> wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Node"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 4f97ac20f79731d8b488792e2e68a6f6ea6a3c66 162 161 2015-06-03T11:41:03Z Chrisr 21 typo wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") ef8125bc78a4f11118234a71b8995b8240ab66a3 167 162 2016-03-26T06:58:44Z Mn1729 23 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"/&gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 27a33e6087d903a3fadb8f09ea58ad585db8b009 168 167 2016-03-26T07:31:45Z Mn1729 23 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 2 6 5''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 296e76ff539924aff9e9c5d13b3f036f0a627a9e 169 168 2016-03-26T11:14:57Z Mn1729 23 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") f0ff962d8d0a423fd55148bced08ff0690364e5b 170 169 2016-03-26T11:17:41Z Mn1729 23 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") ab844afb139b109153da1f1771f9fb5feb311746 172 170 2016-03-26T12:26:29Z Mn1729 23 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 6b7704c1014b81faeb9921abd1ad38f555babb08 173 172 2016-03-26T12:48:16Z Mn1729 23 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 7c8cbf0d0b9c07877e83d6ff3e1870c9b9eb2177 175 173 2016-03-27T04:55:02Z Mn1729 23 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''XML''' The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 5f112e968e2f3be5c70a282b86eb4281fe0578e4 186 175 2016-04-10T09:48:35Z MDiehl 25 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] [[Xdmf2 Model and Format Archive]] The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") bed4cf18cf121741e8cc3317223d035c492fa84f 187 186 2016-04-10T09:51:48Z MDiehl 25 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 8c238e125fcb1d90a5af1d40e61780cf027421df 188 187 2016-04-10T09:51:59Z MDiehl 25 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF'') . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView and EnSight, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5 or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components : elements, entities, and processing information. In XDMF we<nowiki>'</nowiki>re primarily concerned with the elements. These elements follow the basic form : &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. Additionally XDMF takes advantage of two major extensions to XML : '''XInclude''' As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. '''XPath''' This allows for elements in the XML document and the API to reference specific elements in a document. For example : The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be : '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. '''Entities''' In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. '''XDMF Elements''' The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 71d886df1c680b9327449c62e955d242a7e99777 189 188 2016-04-10T10:04:43Z MDiehl 25 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). '''XdmfItem''' There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. '''Uniform ''' The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. '''Collection and Tree''' Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 160fde70036a07df0cb6ac3d0279f9641d1993eb 190 189 2016-04-10T10:05:49Z MDiehl 25 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. '''HyperSlab and Coordinate''' A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. '''Function''' ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' '''Grid''' The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' '''Topology''' The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. '''Geometry''' The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") e127b1db12ed4f5c4e426d47a9dc8309319b9f11 191 190 2016-04-10T10:06:51Z MDiehl 25 /* XdmfItem */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 2.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be : '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements : '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab and Coordinate==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="2"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children : '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : '''Linear''' * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 '''Arbitrary''' * Mixed - a mixture of unstructured cells '''Structured''' * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity : '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9) : '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' '''Attribute''' The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' '''Set''' The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' '''Time''' The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; '''Information''' There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") ea6a9ab5c5ff43264d0d1cd00a261293ec585df4 192 191 2016-04-10T10:13:19Z MDiehl 25 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====Coordinate==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 9cfdd2acb2ac09344ebf7b3945a693132ba9c3b1 193 192 2016-04-10T10:15:37Z MDiehl 25 /* Grid */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====Coordinate==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ===Uniform, Collection, and Tree=== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ===SubSet=== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") dd7b5dee5945eeabeec516048ac45f0760db4754 194 193 2016-04-10T10:19:01Z MDiehl 25 /* XDMF Elements */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ===Uniform, Collection, and Tree=== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ===SubSet=== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron '''Quadratic''' * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology : [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. '''XML Element (Xdmf ClassName) and Default XML Attributes''' * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 6c55badd698b3bf200cf8a67bf29bfa2b9169737 195 194 2016-04-10T10:20:37Z MDiehl 25 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElement (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 3f94b30f7c0379804b1a13ccf26ac5010612c2f2 196 195 2016-04-19T13:16:06Z Dave.demarle 5 correct type wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default BaseOffset <span style='color:red'>0</span> | # * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 2847f17ff901f5de9f7b9025fe2458439eb0e60c 199 196 2016-04-21T15:26:17Z Jgflemin 26 removed BaseOffset and provided an explanation that this was originally available in XDMF but is not available in XDMF3 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: &lt;ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... &gt; ''CData'' &lt;/ElementTag&gt; Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 40be091c9f67082bb077f443e1ad27a0b6b5d7c2 200 199 2016-05-19T23:34:47Z Crayzeewulf 24 /* Elements */ Placed XML code in source tag so it is easier to edit and is lot easier to read. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude]</nowiki>"&gt;''' '''&lt;xi:include href="Example3.xmf"/&gt;''' '''&lt;/Xdmf&gt;''' the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 1681b8689df563ac165e8cdad0249565996a636f User:Mn1729 2 33 163 2016-03-25T13:53:14Z Dave.demarle 5 Creating user page for new user. wikitext text/x-wiki I use HDF for meshes and found some mistakes in some of the xml file formats on this page. I would like to correct them for future users. 06991b38b4b8c65c2c68bb881fdf71674cedd44a User talk:Mn1729 3 34 164 2016-03-25T13:53:14Z Dave.demarle 5 Welcome! wikitext text/x-wiki '''Welcome to ''XdmfWeb''!''' We hope you will contribute much and well. You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages]. Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 09:53, 25 March 2016 (EDT) a083f18f45c690779f899ae6874eae904175c4f6 User:Crayzeewulf 2 35 165 2016-03-25T15:08:46Z WikiSysop 11 Creating user page for new user. wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 User talk:Crayzeewulf 3 36 166 2016-03-25T15:08:46Z WikiSysop 11 Welcome! wikitext text/x-wiki '''Welcome to ''XdmfWeb''!''' We hope you will contribute much and well. You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages]. Again, welcome and have fun! [[User:WikiSysop|WikiSysop]] ([[User talk:WikiSysop|talk]]) 11:08, 25 March 2016 (EDT) 1ce72ee2a7e5396f9474387d6409628bedd2b3de File:3DUnstructuredMesh.jpeg 6 37 171 2016-03-26T12:06:29Z Mn1729 23 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 File:3DUnstructuredParaView.png 6 38 174 2016-03-27T04:48:28Z Mn1729 23 wikitext text/x-wiki da39a3ee5e6b4b0d3255bfef95601890afd80709 Get Xdmf 0 20 176 123 2016-04-02T19:37:53Z Dave.demarle 5 wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on zlib and hdf5 and had a header only dependency on boost. You must obtain and build those projects before you can build xdmf. To use Xdmf from Python, Tcl or Java you will also need swig. To obtain xdmf: * git clone git://public.kitware.com/Xdmf.git XDMF * mkdir build * cd build * ccmake .. * make To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake. Xdmf is also mirrored in VTK. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration. 99d8bc7946972d4653ed78f77a55d3369c30ea3e 177 176 2016-04-02T19:38:16Z Dave.demarle 5 wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on zlib and hdf5 and had a header only dependency on boost. You must obtain and build those projects before you can build xdmf. To use Xdmf from Python, Tcl or Java you will also need swig. To obtain xdmf: * git clone git://public.kitware.com/Xdmf.git * mkdir build * cd build * ccmake .. * make To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake. Xdmf is also mirrored in VTK. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration. fa13076929901decd0ef887481f3271f03809740 183 177 2016-04-03T13:01:28Z Dave.demarle 5 wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on hdf5 and has a header only dependency on boost. You must obtain and build those projects before you can build xdmf. To use Xdmf from Python or Java you will also need swig. To obtain xdmf: * git clone git://xdmf.org/Xdmf.git * mkdir build * cd build * ccmake .. * make To use xdmf from wrapped languages you will need to configure XDMF_WRAP_PYTHON, or XDMF_WRAP_JAVA on in ccmake. Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on Module_vtkIOXdmf2 or Module_vtkIOXdmf3 on the advanced options page of you VTK configuration. 63712dcb86cf62a411e1204bf92a001e66746d40 Version 2 0 17 178 107 2016-04-03T12:27:18Z Dave.demarle 5 wikitext text/x-wiki Version "2" of Xdmf is being deprecated but it can be found at: git clone git://xdmf.org/Xdmf.git There were two important branches in the repository, "master" (git SHA 6ca45404) and "pv". The "pv" branch (git SHA 24470abd) was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system. The updates to Xdmf in version 2 are summarized in this paper: [http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792] and this podcast [http://www.rce-cast.com/components/com_podcast/media/40RCE-xdmf.mp3] bcbfc6894dbd1c5d1cdc8b0e26195f2d5cfbadec 179 178 2016-04-03T12:27:45Z Dave.demarle 5 wikitext text/x-wiki Version "2" of Xdmf is being deprecated but it can be found in the history at: git clone git://xdmf.org/Xdmf.git There were two important branches in the repository, "master" (git SHA 6ca45404) and "pv". The "pv" branch (git SHA 24470abd) was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system. The updates to Xdmf in version 2 are summarized in this paper: [http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792] and this podcast [http://www.rce-cast.com/components/com_podcast/media/40RCE-xdmf.mp3] f6ae3917d0a158ac3158485a979954d2ba085367 180 179 2016-04-03T12:28:35Z Dave.demarle 5 wikitext text/x-wiki Version "2" of Xdmf is being deprecated but it can be found in the history at: git clone git://xdmf.org/Xdmf.git There were two important branches in the repository, "master" (git SHA 6ca45404) and "pv" (git SHA 24470abd). The "pv" branch was restructured during the ParaView 4 release to update it to be compatible with VTK 6.x's modularized build system. The updates to Xdmf in version 2 are summarized in this paper: [http://www.dtic.mil/cgi-bin/GetTRDoc?AD=ADP023792] and this podcast [http://www.rce-cast.com/components/com_podcast/media/40RCE-xdmf.mp3] 376b0da226cf263432326f98c1347e0fdbe15bc1 Version 3 0 19 181 108 2016-04-03T12:29:55Z Dave.demarle 5 wikitext text/x-wiki Version "3" of Xdmf is the master branch of: git://xdmf.org/Xdmf.git The initial plans for changes that went into version 3 are summarized on: [http://xdmf.org/index.php/Xdmf::New()] The overall goals included better performance and use of modern and more maintainable C++ programming idioms. This version adds a dependence on boost. Additionally, this version added support for Graph types and removed support for the SQL back end. 7e0a0c25a907edf50518617c940c1dcb093a6902 Version 1 0 18 182 101 2016-04-03T12:44:49Z Dave.demarle 5 wikitext text/x-wiki Version "1" of xdmf is deprecated but it can be obtained via: cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf login cvs -d :pserver:anonymous@public.kitware.com:/cvsroot/Xdmf checkout Xdmf c1ef3acaa082158559158a150f25f09ea051b912 User:MDiehl 2 39 184 2016-04-09T21:52:22Z Matthew.bowman 6 Creating user page for new user. wikitext text/x-wiki Scientist, materials science and materials mechanics. b0f4ed02462baadd1c9f264a0cc0d1a5485941f5 User talk:MDiehl 3 40 185 2016-04-09T21:52:22Z Matthew.bowman 6 Welcome! wikitext text/x-wiki '''Welcome to ''XdmfWeb''!''' We hope you will contribute much and well. You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages]. Again, welcome and have fun! [[User:Matthew.bowman|Matthew.bowman]] ([[User talk:Matthew.bowman|talk]]) 17:52, 9 April 2016 (EDT) 0acbb2bb7c2dd9bfa74471bb508b35b4e8645d52 User:Jgflemin 2 41 197 2016-04-19T13:54:43Z Dave.demarle 5 Creating user page for new user. wikitext text/x-wiki I am the Lead Developer and Operator for the ADCIRC Surge Guidance System (ASGS) (https://github.com/jasonfleming/asgs), a software automation system and collection of utilities for the finite element ADCIRC (ADvanced Circulation) coastal ocean model (http://www.adcirc.org). I implemented the i/o code in ADCIRC for natively reading and writing XDMF data files using the Fortran XDMF API. I've also created/maintain/extend standalone utility programs that convert to/from ADCIRC ascii file format to XDMF format using the Fortran XDMF API. Finally, I have created/maintain/extend standalone utility programs that generate XDMF-compliant XML files for ADCIRC's native NetCDF4 formatted output files, taking advantage of the fact that NetCDF4 uses the HDF5 library underneath to write the files. This results in a set of output files that simultaneously satisfies the NetCDF4, HDF5, and XDMF format standards. More information is available from http://www.seahorsecoastal.com. 64193cf17e73f8da35db2d9e1641a5df1884226a User talk:Jgflemin 3 42 198 2016-04-19T13:54:43Z Dave.demarle 5 Welcome! wikitext text/x-wiki '''Welcome to ''XdmfWeb''!''' We hope you will contribute much and well. You will probably want to read the [https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Contents help pages]. Again, welcome and have fun! [[User:Dave.demarle|Dave.demarle]] ([[User talk:Dave.demarle|talk]]) 09:54, 19 April 2016 (EDT) 838d14b561c6547c590636a61807ec7c4466b9dc XDMF Model and Format 0 2 201 200 2016-05-19T23:36:37Z Crayzeewulf 24 /* XInclude */ Placed XML in source tag so it get syntax highlighting and is easier to edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain '''/Xdmf/Domain/Grid''' The tenth Grid .... XPath is one based. '''/Xdmf/Domain/Grid<nowiki>[</nowiki>10<nowiki>]</nowiki>''' The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' '''/Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Copper Plate"<nowiki>]</nowiki>''' All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0"&gt;''' '''&lt;/Xdmf&gt;''' While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 4c1658281b709158aab0d256da85b7f2d077f0ef 202 201 2016-05-19T23:42:07Z Crayzeewulf 24 /* XPath */ Placed code in source tags so it gets syntax highlighting and is easier to edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki>''' '''&lt;!ENTITY cellDimsZYX "45 30 120"&gt;''' '''<nowiki>]</nowiki>&gt;''' the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") bdeade9a01de2b5fceead14f2ddc7bf5ee57773b 203 202 2016-05-19T23:43:35Z Crayzeewulf 24 /* Entities */ Place code in source tags so it gets syntax highlighting and is easier to edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") abf6e554dbc194bebef0086034b628fe2213bd8e 204 203 2016-05-19T23:43:48Z Crayzeewulf 24 /* Entities */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: '''&lt;DataItem ItemType="Uniform"''' '''Format="XML"''' '''NumberType="Float" Precision="4"''' '''Rank="1" Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' Alternatively, an application may store its data in binary files. In this case the XML might be. '''&lt;DataItem ItemType="Uniform"''' '''Format="Binary"''' '''Dimensions="64 128 256"&gt;''' '''PressureFile.bin''' '''&lt;/DataItem&gt;''' Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") cdfb5d5166cd0949e688c876e51eb2537c8c07f2 205 204 2016-05-19T23:48:25Z Crayzeewulf 24 /* Uniform */ Placed code in source tags so it get syntax highlighting and is easier to edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: '''&lt;DataItem Name="Tree Example" ItemType="Tree"&gt;''' '''&lt;DataItem ItemType="Tree"&gt;''' '''&lt;DataItem Name="Collection 1" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''4 5 6 7''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Name="Collection 2" ItemType="Collection"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''7 8 9''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="4"&gt;''' '''10 11 12 13''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' '''&lt;DataItem ItemType="Uniform"''' '''Format="HDF"''' '''NumberType="Float" Precision="8"''' '''Dimensions="64 128 256"&gt;''' '''OutputData.h5:/Results/Iteration 100/Part 2/Pressure''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 1d0c118e6362d6f72755994bce074c66edddedaf 206 205 2016-05-19T23:51:13Z Crayzeewulf 24 /* Collection and Tree */ Cleaned up code indentation. Placed code in source tags so it get syntax highlighting and is easier to edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem '''&lt;DataItem ItemType="HyperSlab"''' '''Dimensions="25 50 75 3"''' '''Type="HyperSlab"&gt;''' '''&lt;DataItem''' '''Dimensions="3 4"''' '''Format="XML"&gt;''' '''0 0 0 0 ''' '''2 2 2 1 ''' '''25 50 75 3''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") f263af9a950780e9a2384cdd98939c69ceedfbe9 207 206 2016-05-19T23:52:50Z Crayzeewulf 24 /* HyperSlab */ Cleaned up code indentation. Placed code in source tags so it gets syntax highlighting and is easier to edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. '''&lt;DataItem ItemType="Coordinate"''' '''Dimensions="2"''' '''Type="Coordinate"&gt;''' '''&lt;DataItem''' '''Dimensions="2 4"''' '''Format="XML"&gt;''' '''0 0 0 1''' '''99 199 299 0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem''' '''Name="Points"''' '''Dimensions="100 200 300 3"''' '''Format="HDF"&gt;''' '''MyData.h5:/XYZ''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") c6e262bb5548c8fd075a42762cb6a5f907425373 208 207 2016-05-19T23:55:03Z Crayzeewulf 24 /* Coordinate */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : '''&lt;DataItem ItemType="Function" ''' '''Function="$0 + $1"''' '''Dimensions="3"&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''1.0 2.0 3.0''' '''&lt;/DataItem&gt;''' '''&lt;DataItem Dimensions="3"&gt;''' '''4.1 5.2 6.3''' '''&lt;/DataItem&gt;''' '''&lt;/DataItem&gt;''' The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element '''&lt;DataItem Name="MyFunction" ItemType="Function"''' ''' Function="10 + $0"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Multiply two arrays (element by element) and take the absolute value ''' &lt;DataItem ItemType="Function"''' ''' Function="ABS($0 <nowiki>*</nowiki> $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Select element 5 thru 15 from the first DataItem ''' &lt;DataItem ItemType="Function"''' ''' Function="$0<nowiki>[</nowiki>5:15<nowiki>]</nowiki>"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Concatenate two arrays ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 ; $1)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' Interlace 3 arrays (Useful for describing vectors from scalar data) ''' &lt;DataItem ItemType="Function"''' ''' Function="JOIN($0 , $1, $2)"&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>1<nowiki>]</nowiki>" /&gt;''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>2<nowiki>]</nowiki>" /&gt; ''' ''' &lt;DataItem Reference="/Xdmf/DataItem<nowiki>[</nowiki>3<nowiki>]</nowiki>" /&gt;''' ''' &lt;/DataItem&gt;''' ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 3ab21dac9044c67002a2c6e20f42e4de7c262477 209 208 2016-05-20T00:00:36Z Crayzeewulf 24 /* Function */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: '''&lt;Grid Name="Car Wheel" GridType="Tree"&gt;''' '''&lt;Grid Name="Tire" GridType="Uniform"&gt;''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nuts" GridType="Collection"&gt;''' '''&lt;Grid Name="Lug Nut 0" GridType="Uniform"''' '''&lt;Topology ....''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 1" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;Grid Name="Lug Nut 2" GridType="Uniform"''' '''&lt;Topology ...''' '''&lt;Geometry ...''' '''&lt;/Grid&gt;''' '''&lt;/Grid&gt;''' '''.''' '''.''' '''.''' ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") a6d5f7e0674bce24ac636f67b64b830c899d6d27 210 209 2016-05-20T00:09:39Z Crayzeewulf 24 /* Uniform, Collection, and Tree */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : ''' &lt;Grid Name="Portion" GridType="Subset" Section="DataItem"&gt;''' ''&lt;!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --&gt;'' ''' &lt;DataItem''' ''' DataType="Int"''' ''' Dimensions="2"''' ''' Format="XML"&gt;''' ''' 0 2''' ''' &lt;/DataItem&gt;''' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="2"&gt;''' ''' 100 150''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' Or ''' &lt;Grid Name="Portion" GridType="Subset" Section="All"&gt;''' ''&lt;!-- Select the entire grid and add an attribute --&gt;'' ''' &lt;Grid Name="Target" Reference="XML"&gt;''' ''' /Xdmf/Domain/Grid<nowiki>[</nowiki>@Name="Main Grid"<nowiki>]</nowiki>''' ''' &lt;/Grid&gt;''' ''' &lt;Attribute Name="New Values" Center="Cell"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 100 150 200''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' ''' &lt;/Grid&gt;''' ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 266e34737da77b5a298cdafc1bfd1f5468e71a9d 211 210 2016-05-20T00:11:20Z Crayzeewulf 24 /* SubSet */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 4facd07c06b3ad2c6d7ad1d1c9a59f818e665fa8 212 211 2016-05-20T00:11:50Z Crayzeewulf 24 /* SubSet */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): '''&lt;Topology TopologyType="Mixed" NumberOfElements="3" &gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="20"&gt;''' '''6 0 1 2 7''' '''3 4 4 5 6 7''' '''9 8 9 10 11 12 13 14 15''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") ba855a9b71e9c53fa658861932d55120483d0f1f 213 212 2016-05-20T03:33:28Z Crayzeewulf 24 /* Structured */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element : '''&lt;Information Name="XBounds" Value="0.0 10.0"/&gt;''' '''&lt;Information Name="Bounds"&gt; 0.0 10.0 100.0 110.0 200.0 210.0 &lt;/Information&gt;''' Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 67141f0bdf071a2b7499f3de7e444057d18986af 214 213 2016-05-20T03:35:19Z Crayzeewulf 24 /* Information */ Cleaned up indentation of XML code. Placed code in source tags so it gets syntax highlighting and is easier to edit and read. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology TopologyType="Quadrilateral" NumberOfElements="2"&gt;''' '''&lt;DataItem Format="XML" DataType="Int" Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry GeometryType="XYZ"&gt;''' '''&lt;DataItem Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] '''&lt;?xml version="1.0" ?&gt;''' '''&lt;!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" <nowiki>[</nowiki><nowiki>]</nowiki>&gt;''' '''&lt;Xdmf Version="2.0" xmlns:xi="<nowiki>[http://www.w3.org/2001/XInclude</nowiki>]"&gt;''' '''&lt;Domain&gt;''' '''&lt;DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"&gt;''' '''0.0 0.0 0.0''' '''1.0 0.0 0.0''' '''1.0 1.0 0.0''' '''0.0 1.0 0.0''' '''0.0 0.0 2.0''' '''1.0 0.0 2.0''' '''1.0 1.0 2.0''' '''0.0 1.0 2.0''' '''&lt;/DataItem&gt;''' '''&lt;Grid Name="Two Quads"&gt;''' '''&lt;Topology Type="Quadrilateral" NumberOfElements="2" &gt;''' '''&lt;DataItem Format="XML" ''' '''DataType="Int"''' '''Dimensions="2 4"&gt;''' '''0 1 2 3''' '''1 6 7 2''' '''&lt;/DataItem&gt;''' '''&lt;/Topology&gt;''' '''&lt;Geometry Type="XYZ"&gt;''' '''&lt;DataItem Reference="XML"&gt;''' '''/Xdmf/Domain/DataItem<nowiki>[</nowiki>@Name="Point Data"<nowiki>]</nowiki>''' '''&lt;/DataItem&gt;''' '''&lt;/Geometry&gt;''' '''&lt;/Grid&gt;''' '''&lt;/Domain&gt;''' '''&lt;/Xdmf&gt;''' ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 522c57b4e250a73b6dfa8be121efca3ee2181f62 215 214 2016-05-20T17:13:14Z Crayzeewulf 24 /* Geometry */ Cleaned up indentation of sample XML code. Placed code in source tags so it gets syntax highlighting and is easier to read/edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : '''&lt;Attribute Name="Node Values" Center="Node"&gt;''' '''&lt;DataItem Format="XML" Dimensions="6 4"&gt;''' '''100 200 300 400''' '''500 600 600 700''' '''800 900 1000 1100''' '''1200 1300 1400 1500''' '''1600 1700 1800 1900''' '''2000 2100 2200 2300''' '''&lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' Or assigned to the cell centers : '''&lt;Attribute Name="Cell Values" Center="Cell"&gt;''' '''&lt;DataItem Format="XML" Dimensions="3"&gt;''' ''' 3000 2000 1000''' ''' &lt;/DataItem&gt;''' '''&lt;/Attribute&gt;''' ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 99c84621e5ccf57c678490a938117fda054797f4 216 215 2016-05-20T17:15:21Z Crayzeewulf 24 /* Attribute */ Cleaned up indentation of XML sample code. Placed all code in source tags so it gets syntax highlighting and is easier to read/edit. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. '''&lt;Set Name="Ids" SetType="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 1 2 3 4''' ''' &lt;/DataItem&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 0 0 0 0''' ''' &lt;/DataItem&gt;''' ''' &lt;Attribute Name="Example" Center="Face"&gt;''' ''' &lt;DataItem Format="XML" Dimensions="4" &gt;''' ''' 100.0 110.0 100.0 200.0''' ''' &lt;/DataItem&gt;''' ''' &lt;/Attribute&gt;''' '''&lt;/Set&gt;''' ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 7dfdd2eeb0b00fef243c207c62abfd49a8a496f6 217 216 2016-05-20T17:17:04Z Crayzeewulf 24 /* Set */ Place XML sample code in source tags so it gets syntax highlighting and is easier to read/modify. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time : '''&lt;Time Value="0.1" /&gt;''' For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time : &lt;Time TimeType="HyperSlab"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="3"&gt; 0.0 0.000001 100 &lt;/DataItem&gt; &lt;/Time&gt; For a collection of grids not written at regular intervals : &lt;Time TimeType="List"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="7"&gt; 0.0 0.1 0.5 1.0 1.1 10.0 100.5 &lt;/DataItem&gt; &lt;/Time&gt; For data which is valid not at a discrete time but within a range : &lt;Time TimeType="Range"&gt; &lt;DataItem Format="XML" NumberType="Float" Dimensions="2"&gt; 0.0 0.5 &lt;/DataItem&gt; &lt;/Time&gt; ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 42943f898447678ecdad4ec539a2fe8b4e35d658 218 217 2016-05-20T17:19:37Z Crayzeewulf 24 /* Time */ Cleaned up indentation of sample XML code. Placed all code in source tags so it gets syntax highlighting and is easier to read/modify. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") d422aef10b574ea3489d358ab9b71d020294907f 219 218 2016-05-20T17:22:12Z Crayzeewulf 24 /* XML Element (Xdmf ClassName) and Default XML Attributes */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 733a9293404824c093365f2d25694698338b6ba2 228 219 2016-10-20T20:25:31Z Stevenwalton 28 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells (see picture to right) ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 42fd47f807ae745d8c6cec7ab8a2bc80184dc999 229 228 2016-12-13T16:02:22Z Burns 17 Xdmf 3 only allows for individual times. wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells (see picture to right) ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. Currently the supported types of values are : * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix These values can be centered on : * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Typically Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 3295c3578935c566a1b1d531c2bccb5bc906ceae 241 229 2017-08-22T14:19:00Z Michal 30 FiniteElementFunction added to /* Attribute */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells (see picture to right) ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain 4 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values * number of degrees of freedom in each cell * ordering of cells First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> <DataItem Dimensions="9 1" NumberType="UInt" Format="XML"> 0 3 6 9 12 15 18 21 24 </DataItem> <DataItem Dimensions="8 1" NumberType="UInt" Format="XML"> 0 1 2 3 4 5 6 7 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> <DataItem Dimensions="9 1" NumberType="UInt" Format="XML"> 0 6 12 18 24 30 36 42 48 </DataItem> <DataItem Dimensions="8 1" NumberType="UInt" Format="XML"> 0 1 2 3 4 5 6 7 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") c77eea73d9db30785be1621452642f836d811812 242 241 2017-08-22T15:46:40Z Michal 30 /* XML Element (Xdmf ClassName) and Default XML Attributes */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells (see picture to right) ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain 4 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values * number of degrees of freedom in each cell * ordering of cells First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> <DataItem Dimensions="9 1" NumberType="UInt" Format="XML"> 0 3 6 9 12 15 18 21 24 </DataItem> <DataItem Dimensions="8 1" NumberType="UInt" Format="XML"> 0 1 2 3 4 5 6 7 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> <DataItem Dimensions="9 1" NumberType="UInt" Format="XML"> 0 6 12 18 24 30 36 42 48 </DataItem> <DataItem Dimensions="8 1" NumberType="UInt" Format="XML"> 0 1 2 3 4 5 6 7 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementType ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 511abb1ae621519f80a4266bcc66780969af0ed6 243 242 2017-08-22T16:46:39Z Michal 30 /* XML Element (Xdmf ClassName) and Default XML Attributes */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells (see picture to right) ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain 4 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values * number of degrees of freedom in each cell * ordering of cells First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> <DataItem Dimensions="9 1" NumberType="UInt" Format="XML"> 0 3 6 9 12 15 18 21 24 </DataItem> <DataItem Dimensions="8 1" NumberType="UInt" Format="XML"> 0 1 2 3 4 5 6 7 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> <DataItem Dimensions="9 1" NumberType="UInt" Format="XML"> 0 6 12 18 24 30 36 42 48 </DataItem> <DataItem Dimensions="8 1" NumberType="UInt" Format="XML"> 0 1 2 3 4 5 6 7 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 181b0eb6d960bebe22604acd751994a0254e9392 244 243 2017-08-22T20:37:42Z Michal 30 /* Attribute */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells (see picture to right) ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") e10c863b812db878a75d36004a480fe6ed13781d 245 244 2018-05-05T12:17:20Z Michal 30 Little inconsistency in GeometryType wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== * Mixed - a mixture of unstructured cells (see picture to right) ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") cd98b4aa13011bac4e72c337d8f08eacb83db599 246 245 2018-05-15T11:34:37Z Houssen 31 Update documentation related to Mixed topology wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 If the cell is not a polyhedron, the list of associated data describing each cell is the list of the indices of each node of the cell. If the cell is a polyhedron, the list of associated data describing each polyhedron is: * number of faces of the polyhedron * for each face: the number of nodes of the face, and, the list of each index of each node Here is an example of an octahedron (polyhedron): <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf xmlns:xi="http://www.w3.org/2003/XInclude" Version="2.2"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </Xdmf> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 8770718916ba85884c53d428309b449288a1d5bf 247 246 2018-05-15T11:38:21Z Houssen 31 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 If the cell is not a polyhedron, the list of associated data describing each cell is the list of the indices of each node of the cell. If the cell is a polyhedron, the list of associated data describing each polyhedron is: * number of faces of the polyhedron * for each face: the number of nodes of the face, and, the list of each index of each node Here is an example of an octahedron (polyhedron): <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 4ea8de6bbd80f495b8cb78826db751054b7bdcfa 248 247 2018-05-15T11:45:37Z Houssen 31 Mixed topology: add octahedron example wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 If the cell is not a polyhedron, the list of associated data describing each cell is the list of the indices of each node of the cell. If the cell is a polyhedron, the list of associated data describing each polyhedron is: * number of faces of the polyhedron * for each face: the number of nodes of the face, and, the list of each index of each node Here is an example of an octahedron (polyhedron): <source lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </source> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triagle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 10244fd96561c382a49d6010f346a56bea78904f 249 248 2018-05-24T13:40:01Z Chrisr 21 fix a typo wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 If the cell is not a polyhedron, the list of associated data describing each cell is the list of the indices of each node of the cell. If the cell is a polyhedron, the list of associated data describing each polyhedron is: * number of faces of the polyhedron * for each face: the number of nodes of the face, and, the list of each index of each node Here is an example of an octahedron (polyhedron): <source lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </source> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 0a523de05c58546b2a2c48b278978b9945ae9df1 250 249 2018-07-14T14:20:14Z Houssen 31 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <source lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </source> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 The list of data describing each cell depends on the cell type. If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell. If the cell is a polygon, the list of data describing each polygon is: * number of nodes the polygon is made of * the (ordered) list of each index of each node If the cell is a polyhedron, the list of data describing each polyhedron is: * number of faces the polyhedron is made of * for each face: the number of nodes of the face, and, the (ordered) list of each index of each node Here is an example of an octahedron (polyhedron): <source lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </source> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 62beaacf413c69e66288fa3a4f5be70010db3ef8 Get Xdmf 0 20 220 183 2016-05-20T17:48:26Z Crayzeewulf 24 Added more detailed instructions for downloading and building Xdmf. wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig]. Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf. * Clone the Git repository: <source lang="sh"> git clone git://xdmf.org/Xdmf.git </source> * Create and enter the directory for building the code: <source lang="sh"> cd Xdmf mkdir build cd build </source> * Prepare the CMake-based build. There are two options *# Use the following command and select options using a text-based menu system:<source lang="sh">ccmake ..</source> *# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following: <source lang="sh"> cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \ -DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev </source> * Make and install Xdmf: <source lang="sh"> make make install </source> To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake. Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration. a300bc13bf4aead23b7f11a1a65579b7cda46240 221 220 2016-05-20T17:51:05Z Crayzeewulf 24 Updated syntax highlighting language. wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig]. Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf. * Clone the Git repository: <source lang="bash"> git clone git://xdmf.org/Xdmf.git </source> * Create and enter the directory for building the code: <source lang="bash"> cd Xdmf mkdir build cd build </source> * Prepare the CMake-based build. There are two options *# Use the following command and select options using a text-based menu system:<source lang="bash">ccmake ..</source> *# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following: <source lang="bash"> export XDMF_INSTALL_DIR=/opt/Xdmf/ cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \ -DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev </source> * Make and install Xdmf: <source lang="bash"> make make install </source> To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake. Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration. 8150509a64c658fecefd87815703371e8ff33f6a 222 221 2016-05-20T17:53:07Z Crayzeewulf 24 Added statement indicating that users will cmake to build Xdmf. Added link to CMake home page. wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. You will need [https://cmake.org/ CMake] to build Xdmf from source code. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig]. Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf. * Clone the Git repository: <source lang="bash"> git clone git://xdmf.org/Xdmf.git </source> * Create and enter the directory for building the code: <source lang="bash"> cd Xdmf mkdir build cd build </source> * Prepare the CMake-based build. There are two options *# Use the following command and select options using a text-based menu system:<source lang="bash">ccmake ..</source> *# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following: <source lang="bash"> export XDMF_INSTALL_DIR=/opt/Xdmf/ cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \ -DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev </source> * Make and install Xdmf: <source lang="bash"> make make install </source> To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake. Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration. 28eab31ff117fbc968bc6352571c55a5c517105c 224 222 2016-07-27T18:05:39Z Crayzeewulf 24 wikitext text/x-wiki The old version of this page can be found at [http://xdmf.org/index.php/Get_Xdmf_original] Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. You will need [https://cmake.org/ CMake] to build Xdmf from source code. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig]. Xdmf development is now being hosted at Kitware's gitlab at: https://gitlab.kitware.com/xdmf/xdmf. See [http://www.kitware.com/pipermail/xdmf/2016-April/000935.html this] post for additional details. Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf. * Clone the Git repository: <source lang="bash"> git clone git://xdmf.org/Xdmf.git </source> or, <source lang="bash"> git clone https://gitlab.kitware.com/xdmf/xdmf.git </source> * Create and enter the directory for building the code: <source lang="bash"> cd Xdmf mkdir build cd build </source> * Prepare the CMake-based build. There are two options *# Use the following command and select options using a text-based menu system:<source lang="bash">ccmake ..</source> *# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following: <source lang="bash"> export XDMF_INSTALL_DIR=/opt/Xdmf/ cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \ -DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev </source> * Make and install Xdmf: <source lang="bash"> make make install </source> To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake. Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration. 81f8bed6bd6a90309d32e5089543ab7dc8ebb7f6 237 224 2017-03-13T14:16:24Z Burns 17 wikitext text/x-wiki The old version of this page can be found [http://xdmf.org/index.php/Get_Xdmf_original here.] Xdmf depends on [https://www.hdfgroup.org/HDF5/ HDF5] and has a header only dependency on [http://www.boost.org/ Boost]. You must obtain and build those projects before you can build Xdmf. You will need [https://cmake.org/ CMake] to build Xdmf from source code. To use Xdmf from Python or Java you will also need [http://www.swig.org/ Swig]. Xdmf development is now being hosted at Kitware's gitlab at: https://gitlab.kitware.com/xdmf/xdmf. See [http://www.kitware.com/pipermail/xdmf/2016-April/000935.html this] post for additional details. Use the following procedure and commands to download, build, and install Xdmf. These instructions assume that the environment variable <code>XDMF_INSTALL_DIR</code> contains the path where you want to install Xdmf. * Clone the Git repository: <source lang="bash"> git clone git://xdmf.org/Xdmf.git </source> or, <source lang="bash"> git clone https://gitlab.kitware.com/xdmf/xdmf.git </source> * Create and enter the directory for building the code: <source lang="bash"> cd Xdmf mkdir build cd build </source> * Prepare the CMake-based build. There are two options *# Use the following command and select options using a text-based menu system:<source lang="bash">ccmake ..</source> *# If you are familiar with CMake, you may set various configuration options on the command line. For example, a typical command line for building Xdmf with Python bindings may look like the following: <source lang="bash"> export XDMF_INSTALL_DIR=/opt/Xdmf/ cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \ -DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev </source> * Make and install Xdmf: <source lang="bash"> make make install </source> To use xdmf from wrapped languages you will need to configure <code>XDMF_WRAP_PYTHON</code>, or <code>XDMF_WRAP_JAVA</code> on in ccmake. Xdmf is mirrored in VTK which has reader and writer classes the call into XDMF to do file IO. To use XDMF within VTK, simply turn on <code>Module_vtkIOXdmf2</code> or <code>Module_vtkIOXdmf3</code> on the advanced options page of you VTK configuration. 02ab867ce6c833b35d83e03f4d9f05af181c7e12 Read Xdmf 0 8 223 146 2016-05-20T17:59:09Z Crayzeewulf 24 /* Reading XDMF Data */ Placed code in source tags so it get syntax highlighting. Cleaned up indentation of the code. wikitext text/x-wiki == Reading XDMF Data == [[Image:TwoHex.jpg]] The following Xdmf XML file is a simple example of a Uniform Grid that contains two Hexahedron that share a face. There are values centered at the nodes and at the cell centers. The values for geometry, connectivity, and scalars are all stored directly in the XML file. <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf> <Domain> <Grid Name="TestGrid"> <Topology Type="Hexahedron" NumberOfElements="2" > <DataItem Format="XML" DataType="Float" Dimensions="2 8"> 0 1 7 6 3 4 10 9 1 2 8 7 4 5 11 10 </DataItem> </Topology> <Geometry Type="XYZ"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="4 3 3"> 0.0 0.0 1.0 1.0 0.0 1.0 3.0 0.0 2.0 0.0 1.0 1.0 1.0 1.0 1.0 3.0 2.0 2.0 0.0 0.0 -1.0 1.0 0.0 -1.0 3.0 0.0 -2.0 0.0 1.0 -1.0 1.0 1.0 -1.0 3.0 2.0 -2.0 </DataItem> </Geometry> <Attribute Name="NodeValues" Center="Node"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="4 3" > 100 200 300 300 400 500 300 400 500 500 600 700 </DataItem> </Attribute> <Attribute Name="CellValues" Center="Cell"> <DataItem Format="XML" DataType="Float" Precision="8" Dimensions="2" > 100 200 </DataItem> </Attribute> </Grid> </Domain> </Xdmf> </source> The XML is stored in the file "MyGrid.xmf". The following Python program demonstrated parsing the XML and retrieving the data values. <source lang="python" line="1"> #! /usr/bin/env python from Xdmf import * reader = XdmfReader.New() dom = XdmfReader.read('MyGrid.xmf') # We now have a tree. Find the one and only Grid element grid = dom.getUnstruturedGrid(0) top = grid.GetTopology() print 'Values = ', top.getValuesString() # Release values from data when done top.release() geo = grid.GetGeometry() print 'Geo Type = ', geo.getType().getName(), ' # Points = ', geo.getNumberPoints() print 'Points = ', geo.getValuesString() geo.release() # for each Attribute, print Light Data and Values for i in range(grid.getNumberAttributes()): attr = grid.getAttribute(i) print 'Attribute ', i, ' Name = ', attr.getName() # Attribute HeavyData is not Updated by default # there could potentially be many causing huge IO attr.read() print 'Values ', attr.getValuesString() attr.release() </source> a52c255a4157453fad70ee09b5ef9ecde1c6763a Main Page 0 1 225 145 2016-09-20T11:13:30Z Arminw 27 /* web site administration */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Xdmf3 Fortran API|Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] * [[V2_To_V3|V2 to V3 Transition and bugs]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [http://public.kitware.com/Bug Mantis Bugtracking system] and select Project:Xdmf from the dropdown list. === Web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 4626a5afa4c53500d4f0c339c63504fe991f7964 226 225 2016-09-20T11:42:01Z Arminw 27 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Xdmf3 Fortran API|Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] * [[V2_To_V3|V2 to V3 Transition and bugs]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [https://gitlab.kitware.com/xdmf/xdmf/issues GitLab issue tracker]. * The GitLab issue tracker is in use since September 2016. Bugs reported before this can be found from the [http://public.kitware.com/Bug/view_all_bug_page.php?project_id=4 Mantis Bugtracking system]. === Web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] 72c16dbd7719ea97a1cdf67c7c199dab78334614 230 226 2017-03-13T13:47:49Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Validate Xdmf's XML]] # [[Xdmf3 Fortran API|Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[V3_Road_Feature_Request|Feature Requests]] * [[V2_To_V3|V2 to V3 Transition and bugs]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [https://gitlab.kitware.com/xdmf/xdmf/issues GitLab issue tracker]. * The GitLab issue tracker is in use since September 2016. Bugs reported before this can be found from the [http://public.kitware.com/Bug/view_all_bug_page.php?project_id=4 Mantis Bugtracking system]. === Web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] ec9aa7c16162eccdc520303a88d69483a85754ae 238 230 2017-03-13T18:15:32Z Burns 17 wikitext text/x-wiki [[Image:XdmfLogo1.gif]] <span style='color:blue'><big>e<span style='color:red'>'''X'''</span>tensible <span style='color:red'>'''D'''</span>ata <span style='color:red'>'''M'''</span>odel and <span style='color:red'>'''F'''</span>ormat</big></span> The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of the eXtensible Data Model and Format (XDMF) . Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView, to a mechanism for performing coupled calculations using multiple, previously stand alone codes. Data format refers to the raw data to be manipulated. Information like number type ( float, integer, etc.), precision, location, rank, and dimensions completely describe the any dataset regardless of its size. The description of the data is also separate from the values themselves. We refer to the description of the data as '''Light''' data and the values themselves as '''Heavy''' data. Light data is small and can be passed between modules easily. Heavy data may be potentially enormous; movement needs to be kept to a minimum. Due to the different nature of heavy and light data, they are stored using separate mechanisms. Light data is stored using XML, Heavy data is typically stored using HDF5. While we could have chosen to store the light data using HDF5 attributes using XML does not require every tool to have access to the compiled HDF5 libraries in order to perform simple operations. Data model refers to the intended use of the data. For example, a three dimensional array of floating point vales may be the X,Y,Z geometry for a grid or calculated vector values. Without a data model, it is impossible to tell the difference. Since the data model only describes the data, it is purely light data and thus stored using XML. It is targeted at scientific simulation data concentrating on scalars, vectors, and tensors defined on some type of computational grid. Structured and Unstructured grids are described via their topology and geometry. Calculated, time varying data values are described as attributes of the grid. The actual values for the grid geometry, connectivity, and attribute values are contained in the data format. This separation of data format and model allows HPC codes to efficiently produce and store vales in a convenient manner without being encumbered by our data model which may be different from their internal arrangement. XDMF uses XML to store Light data and to describe the data Model. HDF5 is used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. The data model in XDMF stored in XML provides the knowledge of what is represented by the Heavy data. In this model, HPC data is viewed as a hierarchy of Domains. A Domain must contain at least one Grid. A Grid is the basic representation of both the geometric and computed/measured values. A Grid is considered to be a group of elements with Structured or Unstructured Topology and their associated values. In addition to the topology of the Grid, Geometry, specifying the X, Y, and Z positions of the Grid is required. Finally, a Grid may have one or more Attributes. Attributes are used to store any other value associated with the grid and may be referenced to the Grid or to individual cells that comprise the Grid. The concept of separating the light data from the heavy data is critical to the performance of this data model and format. HPC codes can read and write data in large, contiguous chunks that are natural to their internal data storage, to achieve optimal I/O performance. If codes were required to significantly re-arrange data prior to I/O operations, data locality, and thus performance, could be adversely affected, particularly on codes that attempt to make maximum use of memory cache. The complexity of the dataset is described in the light data portion, which is small and transportable. For example, the light data might specify a topology of one million hexaherda while the heavy data would contain the geometric XYZ values of the mesh and pressure values at the cell centers stored in large, contiguous arrays. This key feature will allow reusable tools to be built that do not put onerous requirements on HPC codes. Despite the complexity of the organization described in the XML below, the HPC code only needs to produce the three HDF5 datasets for geometry, connectivity, and pressure values. While not required, a C++ API is provided to read and write XDMF data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. '''More Detail''' *[[XDMF Model and Format]] *[[XDMF API]] '''How do I ...''' # [[Get Xdmf]] # [[Read Xdmf]] # [[Write Xdmf]] # [[Validate Xdmf's XML]] # [[Xdmf3 Fortran API|Write from Fortran]] # [[Read from MySQL]] # [[Parallel IO with MPI]] '''Data Format Examples''' * The files for the xdmf3 regression test suite can be obtained from a VTK build tree in $BLDTREE/ExternalData/Testing/Data/XDMF * Generate or read in data to ParaView, and save it into XDMF format. * [http://www.paraview.org/Wiki/ParaView/Data_formats#Reading_a_time_varying_Raw_file_into_Paraview| time varying binary data dumps] * [[examples/imagedata | ImageData from h5 array]] '''History and Road Map''' * [[Version 1]] * [[Version 2]] * [[Version 3]] * [[New Features]] * [[V3_Road_Feature_Request|Feature Requests]] * [[V2_To_V3|V2 to V3 Transition and bugs]] '''Mailing list''' * Join the Xdmf mailing list [http://www.kitware.com/cgi-bin/mailman/listinfo/xdmf here] '''Bug reports''' * To report a bug or request a feature, go to the [https://gitlab.kitware.com/xdmf/xdmf/issues GitLab issue tracker]. * The GitLab issue tracker is in use since September 2016. Bugs reported before this can be found from the [http://public.kitware.com/Bug/view_all_bug_page.php?project_id=4 Mantis Bugtracking system]. === Web site administration === '''Wiki Account''' * Please improve the pages! Send an email to Dave DeMarle at kitware.com with XDMF in the subject that includes your preferred user name and email address in the message body to do so. * [http://www.mediawiki.org/wiki/Help:Configuration_settings Configuration settings list] * [http://www.mediawiki.org/wiki/Help:FAQ MediaWiki FAQ] * [http://mail.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list] f1021945e2b494dd617e7f544a7107bd2158d724 File:MixedTopology.png 6 43 227 2016-10-20T17:04:31Z Stevenwalton 28 Numbers to denote mixed topology. *means that you also need to include number of cells wikitext text/x-wiki Numbers to denote mixed topology. *means that you also need to include number of cells d212f1372ff92d1102a2ebe633978da615a4dc72 Validate Xdmf's XML 0 44 231 2017-03-13T13:51:01Z Burns 17 Created page with "Xdmf's XML can be validated by referencing its .dtd file located at [https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd]" wikitext text/x-wiki Xdmf's XML can be validated by referencing its .dtd file located at [https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd] 8f896b094de415943b16242ad99033d1b403b356 232 231 2017-03-13T13:51:21Z Burns 17 wikitext text/x-wiki Xdmf's XML can be validated by referencing its .dtd file located at this location.[https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd] 7697a3b4d041f6845126b6150d3808612522f52d 233 232 2017-03-13T13:51:40Z Burns 17 wikitext text/x-wiki Xdmf's XML can be validated by referencing its .dtd file (located at this location.)[https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd] 4da0992813d776087b5ee0f1605829f796189abf 234 233 2017-03-13T13:52:45Z Burns 17 wikitext text/x-wiki Xdmf's XML can be validated by referencing its .dtd file located at this location.[https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd] 7697a3b4d041f6845126b6150d3808612522f52d 235 234 2017-03-13T13:53:40Z Burns 17 wikitext text/x-wiki Xdmf's XML can be validated by referencing its .dtd file located [https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd | at this location]. 81470a7f279d09a0ae3f34ea88e98a976a9eb097 236 235 2017-03-13T13:53:55Z Burns 17 wikitext text/x-wiki Xdmf's XML can be validated by referencing its .dtd file located [https://gitlab.kitware.com/xdmf/xdmf/blob/master/Xdmf.dtd at this location]. 450f5af56bb162ea5a1e007b64a6d88a7c66ca58 Parallel IO with MPI 0 12 239 149 2017-03-13T18:17:54Z Burns 17 /* Distributed Shared Memory */ wikitext text/x-wiki <pre style="color: red">Note: as of version 1.8.13 hdf5 must be patched as follows to allow for this functionality.</pre> In the file /hdf5/src/CMakeLists.txt change if (NOT HDF5_INSTALL_NO_DEVELOPMENT) install ( FILES ${H5_PUBLIC_HEADERS} DESTINATION ${HDF5_INSTALL_INCLUDE_DIR} COMPONENT headers ) endif (NOT HDF5_INSTALL_NO_DEVELOPMENT) to if (NOT HDF5_INSTALL_NO_DEVELOPMENT) install ( FILES ${H5_PUBLIC_HEADERS} ${H5_PRIVATE_HEADERS} DESTINATION ${HDF5_INSTALL_INCLUDE_DIR} COMPONENT headers ) endif (NOT HDF5_INSTALL_NO_DEVELOPMENT) ===Distributed Shared Memory=== By leveraging the h5fd and hdf5 libraries, Xdmf provides an interface by which a user can set up a dsm server that may be interacted with in a manner similar to hdf5. Multiple Datasets and filenames are supported as of version 3.3.0. ====Initializing DSM==== After starting MPI, the DSM can be started by creating an instance of XdmfHDF5WriterDSM or XdmfHDF5ControllerDSM. int size, id, dsmSize; dsmSize = 64;//The total size of the DSM being created std::string newPath = "dsm"; unsigned int numServersCores = 2; MPI_Comm comm = MPI_COMM_WORLD; MPI_Init(&argc, &argv); MPI_Comm_rank(comm, &id); MPI_Comm_size(comm, &size); unsigned int dataspaceAllocated = dsmSize/numServersCores; // Splitting MPICommWorld so that a comm that contains the non-Server cores exists. MPI_Comm workerComm; MPI_Group workers, dsmgroup; MPI_Comm_group(comm, &dsmgroup); int * ServerIds = (int *)calloc((numServersCores), sizeof(int)); unsigned int index = 0; for(int i=size-numServersCores ; i <= size-1 ; ++i) { ServerIds[index++] = i; } MPI_Group_excl(dsmgroup, index, ServerIds, &workers); int testval = MPI_Comm_create(comm, workers, &workerComm); cfree(ServerIds); // The last two cores in the Comm are regulated to manage the DSM. shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dataspaceAllocated, size-numServersCores, size-1); This creates a DSM buffer and manager which must be passed to any new DSM objects in order for those objects to function. After the user is finished with DSM the manager must be disposed of. Not doing this will result in an error. if (id == 0) { exampleWriter->stopDSM(); } MPI_Barrier(comm); //the dsmManager must be deleted or else there will be a segfault exampleWriter->deleteManager(); MPI_Finalize(); A full example program can be found in the Xdmf source at: Xdmf/core/dsm/tests/Cxx/DSMLoopTest.cpp 0349b560af07acbb4f0e8318ca5d683dc1569ddb New Features 0 45 240 2017-03-13T18:48:30Z Burns 17 Created page with "Here are some new features to Xdmf. Try them out and give us some feedback. == [http://xdmf.org/index.php/Parallel_IO_with_MPI XdmfDSM] has been updated. == It now supports..." wikitext text/x-wiki Here are some new features to Xdmf. Try them out and give us some feedback. == [http://xdmf.org/index.php/Parallel_IO_with_MPI XdmfDSM] has been updated. == It now supports Paging, multiple datasets, and multiple files. == New API == === XML Archive for XdmfWriter === Archives the XML from previous writes and uses it to generate later iterations. Works best in simulations where new data is appended to the file each iteration. shared_ptr<XdmfWriter> writer = XdmfWriter::New(); writer->setRebuildXML(false); === XdmfGridController === Alternative to XPointers, saves on memory by allowing the reading process to leave extra grids on file instead of reading them. shared_ptr<XdmfUnstructuredGrid> equalUnGrid = XdmfUnstructuredGrid::New(); shared_ptr<XdmfGridController> unGridController = XdmfGridController::New("gridControllerReference.xmf", "/Xdmf/Domain/Grid[1]"); equalUnGrid->setGridController(unGridController); A full example program can be found in the Xdmf source at: Xdmf2/tests/Cxx/TestXdmfGridController.cpp Will be usable in Paraview when it is updated to use the latest Xdmf. === XdmfTemplate === Allows for a grid collection to be written as a compressed grid. A full example program can be found in the Xdmf source at: Xdmf2/tests/Cxx/TestXdmfGridTemplate.cpp Requires a patch to VTK to render in Paraview: In file ParaView/VTK/IO/Xdmf3vtkXdmf3DataSet.cxx line 175 change #define DO_DEEPREAD 0 to #define DO_DEEPREAD 1 == Cxx11 replaces Boost == In the case that Cxx11 is available, the Cxx11 version of calls will be used. Reworked the internals of XdmfArray to no longer use boost::variant df6ff4f3ec9eb6ffb2ea5d6aa3f41263ae2496bd XDMF Model and Format 0 2 251 250 2022-12-01T16:29:47Z Jgflemin 26 /* Elements */ source -> pre wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <pre lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </pre> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <source lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </source> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 The list of data describing each cell depends on the cell type. If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell. If the cell is a polygon, the list of data describing each polygon is: * number of nodes the polygon is made of * the (ordered) list of each index of each node If the cell is a polyhedron, the list of data describing each polyhedron is: * number of faces the polyhedron is made of * for each face: the number of nodes of the face, and, the (ordered) list of each index of each node Here is an example of an octahedron (polyhedron): <source lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </source> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 9015e33393c4c2e07b6ba0393bae4c1c76159eb9 252 251 2022-12-01T16:31:11Z Jgflemin 26 /* XInclude */ source -> pre wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <pre lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </pre> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <pre lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </pre> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <source> /Xdmf/Domain/Grid </source> The tenth Grid .... XPath is one based. <source> /Xdmf/Domain/Grid[10] </source> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <source> /Xdmf/Domain/Grid[@Name="Copper Plate"] </source> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </source> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 The list of data describing each cell depends on the cell type. If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell. If the cell is a polygon, the list of data describing each polygon is: * number of nodes the polygon is made of * the (ordered) list of each index of each node If the cell is a polyhedron, the list of data describing each polyhedron is: * number of faces the polyhedron is made of * for each face: the number of nodes of the face, and, the (ordered) list of each index of each node Here is an example of an octahedron (polyhedron): <source lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </source> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 67d7bf6a49a89755379c065ec9dcebbbee95c7ae 253 252 2022-12-01T16:32:34Z Jgflemin 26 /* XPath */ source -> pre wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <pre lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </pre> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <pre lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </pre> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <pre> /Xdmf/Domain/Grid </pre> The tenth Grid .... XPath is one based. <pre> /Xdmf/Domain/Grid[10] </pre> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <pre> /Xdmf/Domain/Grid[@Name="Copper Plate"] </pre> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </pre> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </source> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 The list of data describing each cell depends on the cell type. If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell. If the cell is a polygon, the list of data describing each polygon is: * number of nodes the polygon is made of * the (ordered) list of each index of each node If the cell is a polyhedron, the list of data describing each polyhedron is: * number of faces the polyhedron is made of * for each face: the number of nodes of the face, and, the (ordered) list of each index of each node Here is an example of an octahedron (polyhedron): <source lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </source> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 96cb88354e72f6210574eb9ced2785dede2fba5b 254 253 2022-12-01T16:33:00Z Jgflemin 26 /* Entities */ wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <pre lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </pre> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <pre lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </pre> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <pre> /Xdmf/Domain/Grid </pre> The tenth Grid .... XPath is one based. <pre> /Xdmf/Domain/Grid[10] </pre> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <pre> /Xdmf/Domain/Grid[@Name="Copper Plate"] </pre> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </pre> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </pre> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </source> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <source lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Multiply two arrays (element by element) and take the absolute value <source lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Select element 5 thru 15 from the first DataItem <source lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </source> Concatenate two arrays <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </source> Interlace 3 arrays (Useful for describing vectors from scalar data) <source lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </source> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 The list of data describing each cell depends on the cell type. If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell. If the cell is a polygon, the list of data describing each polygon is: * number of nodes the polygon is made of * the (ordered) list of each index of each node If the cell is a polyhedron, the list of data describing each polyhedron is: * number of faces the polyhedron is made of * for each face: the number of nodes of the face, and, the (ordered) list of each index of each node Here is an example of an octahedron (polyhedron): <source lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </source> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 902312724b21d3cd8453ce6ff5f563dd954b4c49 255 254 2022-12-01T16:34:46Z Jgflemin 26 /* Function */ source -> pre wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <pre lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </pre> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <pre lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </pre> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <pre> /Xdmf/Domain/Grid </pre> The tenth Grid .... XPath is one based. <pre> /Xdmf/Domain/Grid[10] </pre> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <pre> /Xdmf/Domain/Grid[@Name="Copper Plate"] </pre> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </pre> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </pre> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <source lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </source> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </source> Alternatively, an application may store its data in binary files. In this case the XML might be. <source lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </source> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <source lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </source> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <source lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <source lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </source> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </pre> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <pre lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </pre> Multiply two arrays (element by element) and take the absolute value <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </pre> Select element 5 thru 15 from the first DataItem <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </pre> Concatenate two arrays <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </pre> Interlace 3 arrays (Useful for describing vectors from scalar data) <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </pre> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <source lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </source> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </source> Or <source lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </source> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 The list of data describing each cell depends on the cell type. If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell. If the cell is a polygon, the list of data describing each polygon is: * number of nodes the polygon is made of * the (ordered) list of each index of each node If the cell is a polyhedron, the list of data describing each polyhedron is: * number of faces the polyhedron is made of * for each face: the number of nodes of the face, and, the (ordered) list of each index of each node Here is an example of an octahedron (polyhedron): <source lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </source> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <source lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </source> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <source lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </source> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <source lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </source> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <source lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </source> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <source lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </source> Or assigned to the cell centers : <source lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </source> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <source lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </source> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <source lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </source> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <source lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </source> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <source lang="xml" line="1"> <Time Value="0.1" /> </source> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <source lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </source> For a collection of grids not written at regular intervals: <source lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </source> For data which is valid not at a discrete time but within a range: <source lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </source> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <source lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </source> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") 8aa2aac42b0f4e2c0c987d574248f9f292df16d9 256 255 2022-12-01T16:43:07Z Jgflemin 26 source -> pre wikitext text/x-wiki [[Image:XdmfLogo1.gif]] Here the XDMF3 Model and Format is described. See [[Xdmf2 Model and Format Archive]] for the previous version. The need for a standardized method to exchange scientific data between High Performance Computing codes and tools lead to the development of ''the eXtensible Data Model and Format'' (''XDMF''). Uses for XDMF range from a standard format used by HPC codes to take advantage of widely used visualization programs like ParaView[https://www.paraview.org] and EnSight[https://www.ceisoftware.com], to a mechanism for performing coupled calculations using multiple, previously stand alone codes. XDMF categorizes data by two main attributes; size and function. Data can be ''Light'' (typically less than about a thousand values) or ''Heavy'' (megabytes, terabytes, etc.). In addition to raw values, data can refer to ''Format'' (rank and dimensions of an array) or ''Model'' (how that data is to be used. i.e. XYZ coordinates vs. Vector components). XDMF uses XML to store Light data and to describe the data Model. Either HDF5[https://www.hdfgroup.org/HDF5] or binary files can be used to store Heavy data. The data Format is stored redundantly in both XML and HDF5. This allows tools to parse XML to determine the resources that will be required to access the Heavy data. For the binary Heavy data option, the xml must list a filename where the binary data is stored. While not required, a C++ API is provided to read and write '''XDMF''' data. This API has also been wrapped so it is available from popular languages like Python, Tcl, and Java. The API is not necessary in order to produce or consume XDMF data. Currently several HPC codes that already produced HDF5 data, use native text output to produce the XML necessary for valid XDMF. ==XML== The eXtensible Markup Language (XML) format is widely used for many purposes and is well documented at many sites. There are numerous open source parsers available for XML. The XDMF API takes advantage of the libxml2 parser to provide the necessary functionality. Without going into too much detail, XDMF views XML as a "personalized HTML" with some special rules. It it case sensitive and is made of three major components: elements, entities, and processing information. In XDMF the '''element''' is the most important component. Additionally XDMF takes advantage of two major extensions to XML: '''XInclude''' and '''XPath'''. ===Elements=== Elements follow the basic form: <pre lang="xml" line="1"> <ElementTag AttributeName="AttributeValue" AttributeName="AttributeValue" ... > CData </ElementTag> </pre> Each element begins with a &lt;tag&gt; and ends with a &lt;/tag&gt;. Optionally there can be several "Name=Value" pairs which convey additional information. Between the &lt;tag&gt; and the &lt;/tag&gt; there can be other &lt;tag&gt;&lt;/tag&gt; pairs and/or character data (CData). CData is typically where the values are stored; like the actual text in an HTML document. The XML parser in the XDMF API parses the XML file and builds a tree structure in memory to describe its contents. This tree can be queried, modified, and then "serialized" back into XML. Comments in XML start with a "&lt;!--" and end with a "--&gt;". So &lt;!--This is a Comment --&gt;. XML is said to be "well formed" if it is syntactically correct. That means all of the quotes match, all elements have end elements, etc. XML is said to be "valid" if it conforms to the ''Schema'' or ''DTD'' defined at the head of the document. For example, the schema might specify that element type A can contain element B but not element C. Verifying that the provided XML is well formed and/or valid are functions typically performed by the XML parser. ===XInclude=== As opposed to entity references in XML (see below), XInclude allows for the inclusion of files that are not well formed XML. This means that with XInclude the included file could be well formed XML or perhaps a flat text file of values. The syntax looks like this : <pre lang="xml" line="1"> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <xi:include href="Example3.xmf"/> </Xdmf> </pre> the xmlns:xi establishes a namespace xi. Then anywhere within the Xdmf element, xi:include will pull in the URL. ===XPath=== This allows for elements in the XML document and the API to reference specific elements in a document. For example: The first Grid in the first Domain <pre> /Xdmf/Domain/Grid </pre> The tenth Grid .... XPath is one based. <pre> /Xdmf/Domain/Grid[10] </pre> The first grid with an attribute ''Name'' which has a value of ''"Copper Plate"'' <pre> /Xdmf/Domain/Grid[@Name="Copper Plate"] </pre> All valid XDMF must appear between the &lt;Xdmf&gt; and the &lt;/Xdmf&gt; tags. So a minimal (empty) XDMF XML file would be: <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0"> </Xdmf> </pre> While there exists an Xdmf DTD and a Schema they are only necessary for validating parsers. For performance reasons, validation is typically disabled. ===Entities=== In addition to Xinclude and XPath, which allow for references to data outside the actual XMDF, XML's basic substitution mechanism of entities can be used to render the XDMF document more readable. For instance, once an entity alias has been defined in the header via <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" [ <!ENTITY cellDimsZYX "45 30 120"> ]> </pre> the text in double quotes is substituted for the entity reference ''&cellDimsZXY;'' (note the trailing semicolon) whenever the parser encounters the latter in the remaining part of the document. ==XDMF Elements== The organization of XDMF begins with the ''Xdmf'' element. So that parsers can distinguish from previous versions of XDMF, there exists a ''Version'' attribute (currently at 3.0). Any element in XDMF can have a ''Name'' attribute or have a ''Reference'' attribute. The Name attribute becomes important for grids while the Reference attribute is used to take advantage of the XPath facility (more detail on this later). Xdmf elements contain one or more ''Domain'' elements (computational domain). There is seldom motivation to have more than one Domain. A Domain can have one or more ''Grid'' elements. Each Grid contains a ''Topology'', ''Geometry'', and zero or more ''Attribute'' elements. Topology specifies the connectivity of the grid while Geometry specifies the location of the grid nodes. Attribute elements are used to specify values such as scalars and vectors that are located at the node, edge, face, cell center, or grid center. To specify actual values for connectivity, geometry, or attributes, XDMF defines a ''DataItem'' element. A DataItem can provide the actual values or provide the physical storage (which is typically an HDF5 file). ===XdmfItem=== There are six different types of DataItems : # '''Uniform''' - this is the default. A single array of values. # '''Collection''' - a one dimension array of DataItems # '''Tree''' - a hierarchical structure of DataItems # '''HyperSlab''' - contains two data items. The first selects the start, stride and count indexes of the second DataItem. # '''Coordinates''' - contains two DataItems. The first selects the parametric coordinates of the second DataItem. # '''Function''' - calculates an expression. ====Uniform==== The simplest type is Uniform that specifies a single array. As with all XDMF elements, there are reasonable defaults wherever possible. So the simplest DataItem would be : <pre lang="xml" line="1"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> </pre> Since no ''ItemType'' has been specified, Uniform has been assumed. The default ''Format'' is XML and the default ''NumberType'' is a 32 bit floating point value. So the fully qualified DataItem for the same data would be: <pre lang="xml" line="1"> <DataItem ItemType="Uniform" Format="XML" NumberType="Float" Precision="4" Rank="1" Dimensions="3"> 1.0 2.0 3.0 </DataItem> </pre> Since it is only practical to store a small amount of data values in the XML, production codes typically write their data to HDF5 and specify the location in XML. HDF5 is a hierarchical, self describing data format. So an application can open an HDF5 file without any prior knowledge of the data and determine the dimensions and number type of all the arrays stored in the file. XDMF requires that this information also be stored redundantly in the XML so that applications need not have access to the actual heavy data in order to determine storage requirements. For example, suppose an application stored a three dimensional array of pressure values at each iteration into an HDF5 file. The XML might be : <pre lang="xml" line="1"> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </pre> Alternatively, an application may store its data in binary files. In this case the XML might be. <pre lang="xml" line="1"> <DataItem ItemType="Uniform" Format="Binary" Dimensions="64 128 256"> PressureFile.bin </DataItem> </pre> Dimensions are specified with the slowest varying dimension first (i.e. KJI order). The HDF filename can be fully qualified, if it is not it is assumed to be located in the current directory or the same directory as the XML file. ====Collection and Tree==== Collections are Trees with only a single level. This is such a frequent occurrence that it was decided to make a Collection a separate type in case the application can optimize access. Collections and Trees have DataItem elements as children. The leaf nodes are Uniform DataItem elements: <pre lang="xml" line="1"> <DataItem Name="Tree Example" ItemType="Tree"> <DataItem ItemType="Tree"> <DataItem Name="Collection 1" ItemType="Collection"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="4"> 4 5 6 7 </DataItem> </DataItem> </DataItem> <DataItem Name="Collection 2" ItemType="Collection"> <DataItem Dimensions="3"> 7 8 9 </DataItem> <DataItem Dimensions="4"> 10 11 12 13 </DataItem> </DataItem> <DataItem ItemType="Uniform" Format="HDF" NumberType="Float" Precision="8" Dimensions="64 128 256"> OutputData.h5:/Results/Iteration 100/Part 2/Pressure </DataItem> </DataItem> </pre> This DataItem is a tree with three children. The first child is another tree that contains a collection of two uniform DataItem elements. The second child is a collection with two uniform DataItem elements. The third child is a uniform DataItem. ====HyperSlab==== A ''HyperSlab'' specifies a subset of some other DataItem. The slab is specified by giving the start, stride, and count of the values in each of the target DataItem dimensions. For example, given a dataset MyData.h5:/XYZ that is 100x200x300x3, we could describe a region starting at <nowiki>[</nowiki>0,0,0,0<nowiki>]</nowiki>, ending at <nowiki>[</nowiki>50, 100, 150, 2<nowiki>]</nowiki> that includes every other plane of data with the HyperSlab DataItem <pre lang="xml" line="1"> <DataItem ItemType="HyperSlab" Dimensions="25 50 75 3" Type="HyperSlab"> <DataItem Dimensions="3 4" Format="XML"> 0 0 0 0 2 2 2 1 25 50 75 3 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </pre> Notice that the first DataItem specified Start, Stride and Count for each dimension of the second DataItem. ====Coordinate==== Suppose, instead that we only wish to specify the first Y data value from the DataItem and the last X value. This can be accomplished by providing the parametric coordinates of the desired values and using the ''Coordinates'' ItemType. <pre lang="xml" line="1"> <DataItem ItemType="Coordinate" Dimensions="2" Type="Coordinate"> <DataItem Dimensions="2 4" Format="XML"> 0 0 0 1 99 199 299 0 </DataItem> <DataItem Name="Points" Dimensions="100 200 300 3" Format="HDF"> MyData.h5:/XYZ </DataItem> </DataItem> </pre> The first Y value is index 1 of item 0,0,0 while the last X value is index 0 of item 99, 199, 299. The dimensionality of the specified coordinates must match that of the target DataItem. ====Function==== ''Function'' ItemType specifies some operation on the children DataItem elements. The elements are referenced by $X where X is the zero based index of the child. For example, the following DataItem would add the two children DataItem elements together in a value by value operation resulting in the values 5.1, 7.2 and 9.3 : <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="$0 + $1" Dimensions="3"> <DataItem Dimensions="3"> 1.0 2.0 3.0 </DataItem> <DataItem Dimensions="3"> 4.1 5.2 6.3 </DataItem> </DataItem> </pre> The function description can be arbitrarily complex and contain SIN, COS, TAN, ACOS, ASIN, ATAN, LOG, EXP, ABS, and SQRT. In addition, there are the JOIN() and WHERE() expressions. JOIN can concatenate or interlace arrays while WHERE() can extract values where some condition is true. In the following examples we take advantage of the XPath facility to reference DataItem elements that have been previously specified : Add the value 10 to every element <pre lang="xml" line="1"> <DataItem Name="MyFunction" ItemType="Function" Function="10 + $0"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </pre> Multiply two arrays (element by element) and take the absolute value <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="ABS($0 * $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </pre> Select element 5 thru 15 from the first DataItem <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="$0[5:15]"> <DataItem Reference="/Xdmf/DataItem[1]" /> </DataItem> </pre> Concatenate two arrays <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 ; $1)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> </DataItem> </pre> Interlace 3 arrays (Useful for describing vectors from scalar data) <pre lang="xml" line="1"> <DataItem ItemType="Function" Function="JOIN($0 , $1, $2)"> <DataItem Reference="/Xdmf/DataItem[1]" /> <DataItem Reference="/Xdmf/DataItem[2]" /> <DataItem Reference="/Xdmf/DataItem[3]" /> </DataItem> </pre> ===Grid=== The DataItem element is used to define the data format portion of XDMF. It is sufficient to specify fairly complex data structures in a portable manner. The data model portion of XDMF begins with the ''Grid'' element. A Grid is a container for information related to 2D and 3D points, structured or unstructured connectivity, and assigned values. The Grid element now has a GridType attribute. Valid GridTypes are : # '''Uniform''' - a homogeneous single grid (i.e. a pile of triangles) # '''Collection''' - an array of Uniform grids all with the same Attributes # '''Tree''' - a hierarchical group # '''SubSet ''' - a portion of another Grid ====Uniform, Collection, and Tree==== Uniform Grid elements are the simplest type and must contain a ''Topology'' and ''Geometry'' element. If GridType is Collection, a CollectionType can be specified as either "Spatial" or "Temporal". Just like the DataItem element, Tree and Collection Grid elements contain other Grid elements as children: <pre lang="xml" line="1"> <Grid Name="Car Wheel" GridType="Tree"> <Grid Name="Tire" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nuts" GridType="Collection"> <Grid Name="Lug Nut 0" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 1" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> <Grid Name="Lug Nut 2" GridType="Uniform"> <Topology> ... </Topology> <Geometry> ... </Geometry> </Grid> </Grid> . . . </pre> ====SubSet==== A SubSet GridType is used to define a portion of another grid or define new attributes on the grid. This allows users to share the geometry and topology of another grid, the attributes from the original grid are not assigned. The Section attribute of a SubSet can be ''DataItem'' or ''All'' : <pre lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="DataItem"> <!-- Select 2 cells from another grid. Which 2 are defined by the DataItem --> <DataItem DataType="Int" Dimensions="2" Format="XML"> 0 2 </DataItem> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="2"> 100 150 </DataItem> </Attribute> </Grid> </pre> Or <pre lang="xml" line="1"> <Grid Name="Portion" GridType="Subset" Section="All"> <!-- Select the entire grid and add an attribute --> <Grid Name="Target" Reference="XML"> /Xdmf/Domain/Grid[@Name="Main Grid"] </Grid> <Attribute Name="New Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 100 150 200 </DataItem> </Attribute> </Grid> </pre> ===Topology=== The Topology element describes the general organization of the data. This is the part of the computational grid that is invariant with rotation, translation, and scale. For structured grids, the connectivity is implicit. For unstructured grids, if the connectivity differs from the standard, an Order may be specified. Currently, the following Topology cell types are defined : [[File:MixedTopology.png|400px|thumb|alt=Mixed Topology cell number|Mixed Topology Cell Number ''[[*Needs number of cells]]''.]] ====Linear==== * Polyvertex - a group of unconnected points * Polyline - a group of line segments * Polygon * Triangle * Quadrilateral * Tetrahedron * Pyramid * Wedge * Hexahedron ====Quadratic==== * Edge_3 - Quadratic line with 3 nodes * Tri_6 * Quad_8 * Tet_10 * Pyramid_13 * Wedge_15 * Hex_20 ====Arbitrary==== Mixed topology enables to define a mixture of unstructured cells (see picture to right). A cell defined in a mixed topology is made of a type (integer) and a list of associated data (integer) describing the cell. Cell types can be: * 1 - POLYVERTEX * 2 - POLYLINE * 3 - POLYGON * 4 - TRIANGLE * 5 - QUADRILATERAL * 6 - TETRAHEDRON * 7 - PYRAMID * 8 - WEDGE * 9 - HEXAHEDRON * 16 - POLYHEDRON * 34 - EDGE_3 * 35 - QUADRILATERAL_9 * 36 - TRIANGLE_6 * 37 - QUADRILATERAL_8 * 38 - TETRAHEDRON_10 * 39 - PYRAMID_13 * 40 - WEDGE_15 * 41 - WEDGE_18 * 48 - HEXAHEDRON_20 * 49 - HEXAHEDRON_24 * 50 - HEXAHEDRON_27 The list of data describing each cell depends on the cell type. If the cell is neither a polygon nor a polyhedron, the list of data describing each cell is the list of indices of each node of the cell. If the cell is a polygon, the list of data describing each polygon is: * number of nodes the polygon is made of * the (ordered) list of each index of each node If the cell is a polyhedron, the list of data describing each polyhedron is: * number of faces the polyhedron is made of * for each face: the number of nodes of the face, and, the (ordered) list of each index of each node Here is an example of an octahedron (polyhedron): <pre lang="xml" line="1"> <Domain> <Grid Name="Octahedron" GridType="Uniform"> <Topology TopologyType="Mixed"> <DataItem Dimensions="26" NumberType="Int" Precision="4" Format="XML"> <!-- polyhedron cell type = 16, 8 faces, each face = 3 points, 3 point indices --> 16 8 3 0 1 4 3 0 1 5 3 1 2 4 3 1 2 5 3 2 3 4 3 2 3 5 3 3 0 4 3 3 0 5 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Rank="2" Dimensions="6 3" NumberType="Float" Precision="8" Format="XML"> -1. -1. 0. -1. 1. 0. 1. 1. 0. 1. -1. 0. 0. 0. 1. 0. 0. -1. </DataItem> </Geometry> </Grid> </Domain> </pre> ====Structured==== * 2DSMesh - Curvilinear * 2DRectMesh - Axis are perpendicular * 2DCoRectMesh - Axis are perpendicular and spacing is constant * 3DSMesh * 3DRectMesh * 3DCoRectMesh There is a ''NodesPerElement'' attribute for the cell types where it is not implicit. For example, to define a group of Octagons, set TopologyType="Polygon" and NodesPerElement="8". For structured grid topologies, the connectivity is implicit. For unstructured topologies the Topology element must contain a DataItem that defines the connectivity: <pre lang="xml" line="1"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> </pre> The connectivity defines the indexes into the XYZ geometry that define the cell. In this example, the two quads share an edge defined by the line from node 1 to node 2. A Topology element can define ''Dimensions'' or ''NumberOfElements''; this is just added for clarity. Here NumberOfElements defines the number of cells we have (3: 1 Tet, 1 Poly, and 1 Hex) and the dimensions denotes the total number of items used to describe the topology (total of 20). Mixed topologies must define the cell type of every element. If that cell type does not have an implicit number of nodes, that must also be specified. Some cell types will also need to denote how many node points are needed to define the shape. In this example, we define a topology of three cells consisting of a Tet (cell type 6) a Polygon (cell type 3) and a Hex (cell type 9): <pre lang="xml" line="1"> <Topology TopologyType="Mixed" NumberOfElements="3" > <DataItem Format="XML" DataType="Int" Dimensions="20"> 6 0 1 2 7 3 4 4 5 6 7 9 8 9 10 11 12 13 14 15 </DataItem> </Topology> </pre> Notice that the Polygon must define the number of nodes (4) before its connectivity. The cell type numbers are defined in the API documentation. The ''BaseOffset'' attribute for specifying connectivity indices starting at a value other than 0 (e.g., the default starting array index in Fortran is 1) was available in the original XDMF implementation but is not available in XDMF3. ===Geometry=== The Geometry element describes the XYZ values of the mesh. The important attribute here is the organization of the points. The default is XYZ; an X,Y, and Z for each point starting at parametric index 0. Possible organizations are : * '''XYZ''' - Interlaced locations * '''XY''' - Z is set to 0.0 * '''X_Y_Z''' - X,Y, and Z are separate arrays * '''VXVYVZ''' - Three arrays, one for each axis * '''ORIGIN_DXDYDZ''' - Six Values : Ox,Oy,Oz + Dx,Dy,Dz * '''ORIGIN_DXDY''' - Four Values : Ox,Oy + Dx,Dy The following Geometry element defines 8 points : <pre lang="xml" line="1"> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </pre> Together with the Grid and Topology element we now have enough to define a full XDMF XML file (that can be visualized in VisIt or ParaView) that defines two quadrilaterals that share an edge (notice not all points are used): [[File:3DUnstructuredMesh.jpeg|320px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using VisIt)]] <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <Grid Name="Two Quads"> <Topology TopologyType="Quadrilateral" NumberOfElements="2"> <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </pre> It is valid to have DataItem elements to be direct children of the Xdmf or Domain elements. This could be useful if several Grids share the same Geometry but have separate Topology: [[File:3DUnstructuredParaView.png|450px|thumb|right|An unstructured mesh consisting of two quadrilaterals that share an edge (visualized using ParaView)]] <pre lang="xml" line="1"> <?xml version="1.0" ?> <!DOCTYPE Xdmf SYSTEM "Xdmf.dtd" []> <Xdmf Version="2.0" xmlns:xi="[http://www.w3.org/2001/XInclude]"> <Domain> <DataItem Name="Point Data" Format="XML" Dimensions="2 4 3"> 0.0 0.0 0.0 1.0 0.0 0.0 1.0 1.0 0.0 0.0 1.0 0.0 0.0 0.0 2.0 1.0 0.0 2.0 1.0 1.0 2.0 0.0 1.0 2.0 </DataItem> <Grid Name="Two Quads"> <Topology Type="Quadrilateral" NumberOfElements="2" > <DataItem Format="XML" DataType="Int" Dimensions="2 4"> 0 1 2 3 1 6 7 2 </DataItem> </Topology> <Geometry GeometryType="XYZ"> <DataItem Reference="XML"> /Xdmf/Domain/DataItem[@Name="Point Data"] </DataItem> </Geometry> </Grid> </Domain> </Xdmf> </pre> ===Attribute=== The Attribute element defines values associated with the mesh. There are three attributes which defines what type of data is associated with the mesh. '''AttributeType''' specifies a rank of data stored on mesh, it could be one of: * '''Scalar''' * '''Vector''' * '''Tensor''' - 9 values expected * '''Tensor6''' - a symmetrical tensor * '''Matrix ''' - an arbitrary NxM matrix '''Center''' defines where data are centered and it could take values from: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' * '''Grid''' * '''Other''' A Grid centered Attribute might be something like "Material Type" where the value is constant everywhere in the grid. Edge and Face centered values are defined, but do not map well to many visualization systems (ParaView, for example, ignores them at present). Edge and Face values are defined for each Cell in turn, using VTK ordering. The same Face or Edge may be visited multiple times, with duplicate values. Other centered attributed is currently used only with FiniteElementFunction ItemType. FiniteElementFunction has data centered on nodes, midpoints, centroids, etc. and combination of them. For this reason the centering is called Other. '''ItemType''' determines if and how data should be treated in a special way. There is only one currently supported ItemType *'''FiniteElementFunction''' and only in the case of FiniteElementFunction there are additional attributes '''ElementFamily''' with options: *'''CG''' *'''DG''' *'''Q''' *'''DQ''' *'''RT''' and '''ElementDegree''' taking arbitrary integer value and '''ElementCell''' with options: *'''interval''' *'''triangle''' *'''tetrahedron''' *'''quadrilateral''' *'''hexahedron''' Attribute with ItemType="FiniteElementFunction" '''must contain at least 2 children DataItem elements'''. They define in the following order(!): * indices to degrees of freedom values (in finite element codes also called dofmap) * degrees of freedom values First DataItem defines indices to degrees of freedom values. These are cell-wise indices to the second DataItem array. Second DataItem defines values of degrees of freedom. These are actual values that define finite element function. In the language of finite element theory, degrees of freedom are dual mappings which define the finite element. Their values are evaluations of these duals on the finite element function. For ElementFamily="CG/DG/Q/DQ" these values are actual values of the function at nodes. Nodes coincide with nodes of VTK cell types, the only thing different is their ordering. (Non-trivial) Permutations from XDMF's FiniteElementFunction order to VTK order are: * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="triangle" maps to VTK_QUADRATIC_TRIANGLE nodes as '''{0, 1, 2, 5, 3, 4}''' * ElementFamily="CG/DG", ElementDegree="2" and ElementCell="tetrahedron" maps to VTK_QUADRATIC_TETRA nodes as '''{0, 1, 2, 3, 9, 6, 8, 7, 5, 4}''' * ElementFamily="Q/DQ", ElementDegree="1" and ElementCell="quadrilateral" maps to VTK_QUAD nodes as (lexicographic) '''{0, 1, 3, 2}''' * ElementFamily="Q/DQ", ElementDegree="2" and ElementCell="quadrilateral" maps to VTK_BIQUADRATIC_QUAD nodes as (lexicographic) '''{0, 1, 4, 3, 2, 7, 5, 6, 8}''' VTK ordering of nodes is depicted in VTK "File Formats" manual. XDMF ordering is inspired with finite element code FEniCS (www.fenicsproject.org and femtable.org). ==== Examples of usage of Attribute:==== Typically simple Attributes are assigned on the Node : <pre lang="xml" line="1"> <Attribute Name="Node Values" Center="Node"> <DataItem Format="XML" Dimensions="6 4"> 100 200 300 400 500 600 600 700 800 900 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2100 2200 2300 </DataItem> </Attribute> </pre> Or assigned to the cell centers : <pre lang="xml" line="1"> <Attribute Name="Cell Values" Center="Cell"> <DataItem Format="XML" Dimensions="3"> 3000 2000 1000 </DataItem> </Attribute> </pre> An example of Scalar FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function x*y on [1, 1] square mesh): <pre lang="xml" line="1"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Scalar"> <DataItem Dimensions="8 3" NumberType="UInt" Format="XML"> 3 6 4 3 1 4 6 8 7 6 4 7 1 4 2 1 0 2 4 7 5 4 2 5 </DataItem> <DataItem Dimensions="9 1" NumberType="Float" Format="XML"> 0 0 0.5 0 0.25 1 0 0.5 0 </DataItem> </Attribute> </pre> There are 8 cells on which the function is stored. From the first DataItem we can see, that for the first cell first three values for degrees of freedom are on indices 3 6 4 of the second array. They take values 0 0 0.25. Because the function family is CG and degree is 1 we know, that these values are values of piecewise linear function on triangle's vertices. The ordering of these values is the same as VTK ordering, if it wasn't we would need to apply permutations defined above. An example of Vector FiniteElementFunction of family "CG" and degree "1" living on 2D simplicial mesh is (it is function (x, y) on [1, 1] square mesh): <pre lang="xml"> <Attribute ItemType="FiniteElementFunction" ElementFamily="CG" ElementDegree="1" ElementCell="triangle" Name="u" Center="Other" AttributeType="Vector"> <DataItem Dimensions="8 6" NumberType="UInt" Format="XML"> 6 12 8 7 13 9 6 2 8 7 3 9 12 16 14 13 17 15 12 8 14 13 9 15 2 8 4 3 9 5 2 0 4 3 1 5 8 14 10 9 15 11 8 4 10 9 5 11 </DataItem> <DataItem Dimensions="18 1" NumberType="Float" Format="XML"> 0 1 0 0.5 0.5 1 0 0 0.5 0.5 1 1 0.5 0 1 0.5 1 0 </DataItem> </Attribute> </pre> Unlike in the AttributeType="Scalar" case the function has now 6 values of degrees of freedom per each cell. It corresponds to two components of each of three nodal values. There are 6 degrees of freedom indexed 6 12 8 7 13 9 with values 0 0.5 0.5 0 0 0.5 for the first cell. Because AttributeType="Vector" and mesh has topological dimension 2 we expect vector to have 2 components. These 6 values iterates first through nodes, then through vector components. It means that that function has values (0, 0) (0.5, 0) (0.5, 0.5). ===Set=== The '''Set''' element may be used to define Attributes on a subset of entities of a '''Grid'''. Valid SetTypes are: * '''Node''' * '''Edge''' * '''Face''' * '''Cell''' '''Set''' may have multiple DataItems. The last DataItem always provides the indices of the entity. If SetType is Face or Edge, the First DataItem defines the Cell indices, and subsequent Dataitems define the Cell-local Face or Edge indices. It is therefore possible to define multiple values on Edges or Faces. The following example defines values on Face 0 of Cells 1,2,3 and 4. <pre lang="xml" line="1"> <Set Name="Ids" SetType="Face"> <DataItem Format="XML" Dimensions="4" > 1 2 3 4 </DataItem> <DataItem Format="XML" Dimensions="4" > 0 0 0 0 </DataItem> <Attribute Name="Example" Center="Face"> <DataItem Format="XML" Dimensions="4" > 100.0 110.0 100.0 200.0 </DataItem> </Attribute> </Set> </pre> ===Time=== The '''Time''' element is a child of the '''Grid''' element and specifies the temporal information for the grid. Xdmf3 only supports a single time value for each grid. Older versions allow use of different TimeTypes. The type of time element is defined by the '''TimeType''' attribute of the element. Valid TimeTypes are : * '''Single''' - A single time value for the entire grid * '''HyperSlab''' - Start, Stride, Count * '''List''' - A list of discrete times * '''Range''' - Min, Max So in the simplest form, specifying a single time: <pre lang="xml" line="1"> <Time Value="0.1" /> </pre> For a more complex situation, consider a grid with GridType="Collection" which contains a set 100 children grids written every 1usec of simulation time: <pre lang="xml" line="1"> <Time TimeType="HyperSlab"> <DataItem Format="XML" NumberType="Float" Dimensions="3"> 0.0 0.000001 100 </DataItem> </Time> </pre> For a collection of grids not written at regular intervals: <pre lang="xml" line="1"> <Time TimeType="List"> <DataItem Format="XML" NumberType="Float" Dimensions="7"> 0.0 0.1 0.5 1.0 1.1 10.0 100.5 </DataItem> </Time> </pre> For data which is valid not at a discrete time but within a range: <pre lang="xml" line="1"> <Time TimeType="Range"> <DataItem Format="XML" NumberType="Float" Dimensions="2"> 0.0 0.5 </DataItem> </Time> </pre> ===Information=== There is regularly code or system specific information that needs to be stored with the data that does not map to the current data model. There is an ''Information'' element. This is intended for application specific information that can be ignored. A good example might be the bounds of a grid for use in visualization. Information elements have a Name and Value attribute. If Value is nonexistent the value is in the CDATA of the element: <pre lang="xml" line="1"> <Information Name="XBounds" Value="0.0 10.0"/> <Information Name="Bounds"> 0.0 10.0 100.0 110.0 200.0 210.0 </Information> </pre> Several items can be addressed using the ''Information'' element like time, units, descriptions, etc. without polluting the XDMF schema. If some of these get used extensively they may be promoted to XDMF elements in the future. ===XML Element (Xdmf ClassName) and Default XML Attributes=== Default values are shown in <span style='color:red'>red</span>. * Attribute (XdmfAttribute) Name (no default) AttributeType <span style='color:red'>Scalar</span> | Vector | Tensor | Tensor6 | Matrix | GlobalID Center <span style='color:red'>Node</span> | Cell | Grid | Face | Edge | Other ItemType (no default) | FiniteElementFunction ElementFamily (no default) | CG | DG | Q | DQ | RT (Only Meaningful if ItemType="FiniteElementFunction") ElementDegree (no default) (Only Meaningful if ItemType="FiniteElementFunction") ElementCell (no default) | interval | triangle | tetrahedron | quadrilateral | hexahedron (Only Meaningful if ItemType="FiniteElementFunction") * DataItem (XdmfDataItem) Name (no default) ItemType <span style='color:red'>Uniform</span> | Collection | tree | HyperSlab | coordinates | Function Dimensions (no default) in KJI Order NumberType <span style='color:red'>Float</span> | Int | UInt | Char | UChar Precision 1 | 2 (Int or UInt only) |<span style='color:red'>4</span> | 8 Format <span style='color:red'>XML</span> | HDF | Binary Endian <span style='color:red'>Native</span> | Big | Little (applicable only to Binary format) Compression <span style='color:red'>Raw</span>|Zlib|BZip2 (applicable only to Binary format and depend on xdmf configuration) Seek <span style='color:red'>0</span> (number of bytes to skip, applicable only to Binary format with Raw compression) * Domain (XdmfDomain) Name (no default) * Geometry (XdmfGeometry) GeometryType <span style='color:red'>XYZ</span> | XY | X_Y_Z | VxVyVz | Origin_DxDyDz | Origin_DxDy * Grid (XdmfGrid) Name (no default) GridType <span style='color:red'>Uniform</span> | Collection | Tree | Subset CollectionType <span style='color:red'>Spatial</span> | Temporal (Only Meaningful if GridType="Collection") Section <span style='color:red'>DataItem</span> | All (Only Meaningful if GridType="Subset") * Information (XdmfInformation) Name (no default) Value (no default) * Xdmf (XdmfRoot) Version <span style='color:red'>Current Version</span> | * * Topology (XdmfTopology) Name (no default) TopologyType Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Pyramid| Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Hexahedron_20 | Mixed | 2DSMesh | 2DRectMesh | 2DCoRectMesh | 3DSMesh | 3DRectMesh | 3DCoRectMesh NodesPerElement (no default) Only Important for Polyvertex, Polygon and Polyline NumberOfElements (no default) OR Dimensions (no default) Order each cell type has its own default * Time TimeType <span style='color:red'>Single</span> | HyperSlab | List | Range Value (no default - Only valid for TimeType="Single") c6b87ee661b143d4a97024b636204788e483898d